예제 #1
0
    def _connect_to_odrive(self):
        """
        Connect to the odrive
        """
        print("finding YZ odrive...")
        self.odrv_YZ = odrive.find_any(serial_number="208037743548")

        assert self.odrv_YZ != None
        assert not isinstance(self.odrv_YZ, list)

        print("finding X odrive...")
        self.odrv_X = odrive.find_any(serial_number="3762364A3137")

        assert self.odrv_X != None
        assert not isinstance(self.odrv_X, list)

        self.axes = {
            "X": self.odrv_X.axis0,
            "Y": self.odrv_YZ.axis1,
            "Z": self.odrv_YZ.axis0
        }
        print("ODrives are connected, dumping previous errors")
        # ODrive dose not clear errors with a reconnection, and will refuse to take action until they are cleared
        print("YZ Odrive Errors:")
        dump_errors(self.odrv_YZ, True)
        print("X Odrive Errors:")
        dump_errors(self.odrv_X, True)
        print("\n\n")
        # If there is an error, it configures it back to idle
        for axis_id in self.axes:
            self._set_state(axis_id, AXIS_STATE_CLOSED_LOOP_CONTROL)
        # If it errers from a set state, then the configuration is broken
        self.check_errors()
예제 #2
0
def check_errors(axis):
    if axis.error != 0:
        print("ERROR:")
        dump_errors(odrv_YZ, True)
        dump_errors(odrv_X, True)

        print("Quiting due to error...")
        sys.exit()
예제 #3
0
 def clear_errors(self, event):
     # Non-critical code for clearing error states. To be run with ros.timer
     if self.driver.axis0.error or self.driver.axis1.error:
         rospy.logerr("Axis Error %s %s" %
                      (self.driver.axis0.error, self.driver.axis1.error))
         rospy.logerr("Controller Error %s %s" %
                      (self.driver.axis0.controller.error,
                       self.driver.axis1.controller.error))
     o_utils.dump_errors(self.driver, clear=True)
 def clearE(self):
     # Edit by GGC on June 28
     # An attempt to clear odrive errors
     if not self.driver:
         self.logger.error("Not connected.")
         return False
     else:
         print(dump_errors(self.driver))
         dump_errors(self.driver, True)
         return True
예제 #5
0
    def on_event(self, event):
        global modrive

        if (event == "arm cmd"):
            modrive.arm()
            return ArmedState()

        if (modrive.check_errors()):
            print("clearing calibration errors")
            dump_errors(modrive.odrive, True)

        return self
예제 #6
0
def wait_and_exit_on_error(ax):
    while ax.current_state != AXIS_STATE_IDLE:
        time.sleep(0.1)
        for odrv in odrvs:
            odrv.axis0.watchdog_feed()
            odrv.axis1.watchdog_feed()
    if ax.error != errors.axis.ERROR_NONE:
        for odrv in odrvs:
            if (ax == odrv.axis0 or ax == odrv.axis1):
                dump_errors(odrv, True)

        exit()
예제 #7
0
    def check_errors(self):
        """
        Check to see if the odrive encountered any errors, will just eject if errors are found.
        """
        self._check_connected()
        for axis in self.axes.values():
            if axis.error != 0:
                print("ERROR:")
                dump_errors(self.odrv_YZ, True)
                dump_errors(self.odrv_X, True)

                print("Quiting due to error...")
                sys.exit()
예제 #8
0
    def on_event(self, event):
        """
        Handle events that are delegated to the Error State.
        """
        global modrive
        dump_errors(modrive.odrive, True)

        if (event == "odrive error"):
            try:
                modrive.reboot()  # only runs after initial pairing
            except:
                print('channel error caught')
            return DisconnectedState()

        return self
예제 #9
0
    def calibrate(self):
        dump_errors(self.odrive, True)  # clears all odrive encoder errors
        self._requested_state(AXIS_STATE_FULL_CALIBRATION_SEQUENCE)

        front_state, back_state = self.get_current_state()

        # if both axes are idle it means its done calibrating
        while (front_state != AXIS_STATE_IDLE
               or back_state != AXIS_STATE_IDLE):
            front_state, back_state = self.get_current_state()
            pass

        self._pre_calibrate(self.front_axis)
        self._pre_calibrate(self.back_axis)
        self.odrive.save_configuration()
예제 #10
0
    def __init__(self):
        # CONSTANTS
        self.MIN_MOTOR_RADS = 104  # So min wheel speed is ~50 RPM
        self.MAX_MOTOR_RADS = 471  # So max wheel speed is ~200 RPM

        self.MAX_EFFORT = 20

        # Encoder counts per radian the MOTOR has turned
        self.ENCODER_COUNTS_PER_RAD = 4000 / (2 * 3.1415926)

        # Encoder counts from the wheels
        self._encoder_counts = [0, 0]

        # Find the Odrive - block until received
        print("\033[1;31mWaiting for Odrive...\033[0m")
        self._odrv = odrive.find_any()
        print("\033[1;32m...Found Odrive\033[0m")

        # Do initial callibration
        self._odrv.axis0.requested_state = AXIS_STATE_FULL_CALIBRATION_SEQUENCE
        self._odrv.axis1.requested_state = AXIS_STATE_FULL_CALIBRATION_SEQUENCE
        while (self._odrv.axis0.current_state != AXIS_STATE_IDLE
               and self._odrv.axis1.current_state != AXIS_STATE_IDLE):
            time.sleep(0.1)

        if self._odrv.axis0.error != 0x00 or self._odrv.axis1.error != 0x00:
            dump_errors(self._odrv, True)
            raise RuntimeError("Failed to calibrate axis")

        # Set ourselves to the reset state
        self.reset()

        # Ensure that we're in velocity control
        self._odrv.axis0.controller.config.control_mode = CTRL_MODE_VELOCITY_CONTROL
        self._odrv.axis1.controller.config.control_mode = CTRL_MODE_VELOCITY_CONTROL

        self._ctrl_modes = [
            CTRL_MODE_VELOCITY_CONTROL, CTRL_MODE_VELOCITY_CONTROL
        ]
예제 #11
0
def start(odrv):
    print("--------------------------------------")
    dump_errors(odrv, True)
    if (odrv.axis0.encoder.config.pre_calibrated
            and odrv.axis1.encoder.config.pre_calibrated) != 1:
        print(
            "System not calibrated - proceeding to calibration based on index search"
        )
        calibrate.first_time_calibration(odrv)

    configure.currents(odrv)
    configure.velocity_limit(odrv)
    configure.gains(odrv)
    configure.trap_traj(odrv, vel_lim=1, accel_lim=8)

    calibrate.set_encoder_zero(odrv)
    time.sleep(.2)
    update_time_errors(odrv)

    print("DONE start robo")
    print("--------------------------------------")
    print()
예제 #12
0
def start(odrv):

    dump_errors(odrv, True)
    if (odrv.axis0.encoder.config.pre_calibrated
            and odrv.axis1.encoder.config.pre_calibrated) != 1:
        print(
            "System not calibrated - proceeding to calibration based on index search"
        )
        calibrate.first_time_calibration(odrv)

    configure.currents(odrv)
    configure.velocity_limit(odrv)
    configure.gains(odrv,
                    gan_pos=25,
                    gan_vel=250 / 1000.0,
                    gan_int_vel=400 / 1000.0)
    configure.trap_traj(odrv, vel_lim=6, accel_lim=48)

    calibrate.set_encoder_zero(odrv)
    time.sleep(.2)
    update_time_errors(odrv)

    return "DONE start robo"
예제 #13
0
    def on_event(self, event):
        """
        Handle events that are delegated to the Error State.
        """
        global modrive
        print(dump_errors(modrive.odrive, True))
        if (event == OdriveEvent.ODRIVE_ERROR):
            try:
                modrive.reboot()  # only runs after initial pairing
            except Exception:
                pass

            return DisconnectedState()

        return self
예제 #14
0
def set_params(ax):

    dump_errors(ax, True)
    odrv.axis0.watchdog_feed()
    odrv.axis1.watchdog_feed()

    # --- Time BEGIN here
    readwrite_time_start = rospy.Time.now().to_sec()

    for i in range(0, 10001):
        # Either read or write 10000 times, NOT both!
        # ----- MOTOR (READ) -----
        # print("Calibrating ODrive # {}".format(to_calib.index(odrv)))
        # print("motor config.resistance_calib_max_voltage is " + str(ax.motor.config.resistance_calib_max_voltage))

        # # ----- ENCODER (WRITE) -----
        # print('assigning new bandwidth...')
        ax.encoder.config.bandwidth = 100
        # print("Loop Counter: " + str(i))

    # -- Time STOP: Calculate time taken to reset ODrive
    rospy.logdebug(
        "Reading/Writing took {} seconds".format(rospy.Time.now().to_sec() -
                                                 readwrite_time_start))
예제 #15
0
import odrive
from odrive.enums import *
from odrive.utils import start_liveplotter, dump_errors
import time
import math
import numpy
import time

# Find a connected ODrive (this will block until you connect one)
print("finding an odrive...")
my_drive = odrive.find_any()
dump_errors(my_drive,True)

# Find an ODrive that is connected on the serial port /dev/ttyUSB0
#my_drive = odrive.find_any("serial:/dev/ttyUSB0")

#use the plotter to monitor the current and position
# start_liveplotter(lambda: [(my_drive.axis0.motor.current_control.Iq_measured*100),my_drive.axis0.encoder.count_in_cpr])
start_liveplotter(lambda: [(my_drive.axis0.controller.input_pos),my_drive.axis0.encoder.pos_estimate])


# Calibrate motor and wait for it to finish
print("starting calibration...")
my_drive.axis0.requested_state = AXIS_STATE_FULL_CALIBRATION_SEQUENCE
while my_drive.axis0.current_state != AXIS_STATE_IDLE:
    time.sleep(0.1)

my_drive.axis0.requested_state = AXIS_STATE_CLOSED_LOOP_CONTROL
time.sleep(5)
# EXAMPLE
# Read and print the voltage property
예제 #16
0
def clear_errors(odrv):
    dump_errors(odrv, True)
예제 #17
0
def wait_and_exit_on_error(ax):
    while ax.current_state != AXIS_STATE_IDLE:
        time.sleep(0.1)
    if ax.error != errors.axis.ERROR_NONE:
        dump_errors(odrv, True)
        exit()
예제 #18
0
def check_error(odrv_axis, message):
    if (odrv_axis.error != 0):
        print(dump_errors(odrv_axis))
        sys.exit(message)
예제 #19
0
 def clear_errors(self, event):
     # Non-critical code for clearing error states. To be run with ros.timer
     if port == "207C37863548" and self.driver.axis0.error:
         rospy.logerr(self.driver.axis0.error)
     o_utils.dump_errors(self.driver, clear=True)
예제 #20
0
    def __init__(self, timeout):

        # specify left, middle, and right ODrives
        rospy.loginfo("Looking for ODrives...")

        self.SERIAL_NUMS = [
            35593293288011,  # Left, 0
            35623406809166,  # Middle, 1
            35563278839886
        ]  # Right, 2

        rospy.loginfo("Getting odrives first time")
        self.get_odrives()

        rospy.loginfo("Erasing and restarting odrives")

        for odrv in self.odrvs:
            odrv.erase_configuration()
            try:
                odrv.reboot()
            except ChannelBrokenException:
                pass

        rospy.loginfo("Reconnecting to odrives")
        self.get_odrives()
        rospy.loginfo("Reconnected!")

        # Set left and right axis
        self.leftAxes = [
            self.odrvs[0].axis0, self.odrvs[0].axis1, self.odrvs[1].axis1
        ]
        self.rightAxes = [
            self.odrvs[1].axis0, self.odrvs[2].axis0, self.odrvs[2].axis1
        ]
        self.axes = self.leftAxes + self.rightAxes

        # Set axis state
        for ax in (self.leftAxes + self.rightAxes):
            ax.watchdog_feed()

        # Clear errors
        for odrv in self.odrvs:
            dump_errors(odrv, True)
            odrv.config.brake_resistance = 0.5

        for ax in (self.leftAxes + self.rightAxes):
            ax.controller.config.vel_gain = 0.01
            ax.controller.config.vel_integrator_gain = 0.05
            ax.controller.config.control_mode = 2
            ax.controller.vel_setpoint = 400
            ax.motor.config.direction = 1
            ax.sensorless_estimator.config.pm_flux_linkage = 5.51328895422 / (
                7 * 140)  # pole pairs = 7, motor kv = 140KV

            # increase current_lim_tolerance
            ax.motor.config.current_lim_tolerance = 20
            # set to ignore illegal hall state and save all changes
            ax.encoder.config.ignore_illegal_hall_state = True

            # calibrate motor
            ax.requested_state = AXIS_STATE_MOTOR_CALIBRATION

            self.wait_and_exit_on_error(ax)

            ax.requested_state = AXIS_STATE_SENSORLESS_CONTROL
            ax.controller.vel_setpoint = 0

        # Sub to topic
        rospy.Subscriber('joy', Joy, self.vel_callback)

        # Set first watchdog
        self.timeout = timeout  # log error if this many seconds occur between received messages
        self.timer = rospy.Timer(rospy.Duration(self.timeout),
                                 self.watchdog_callback,
                                 oneshot=True)
        self.watchdog_fired = False

        # Init other variables
        self.last_msg_time = 0
        self.last_recv_time = 0
        self.next_wd_feed_time = 0

        rospy.loginfo("Ready for topic")
        rospy.spin()
예제 #21
0
    def __init__(self, timeout):
        
        # specify left, middle, and right ODrives
        rospy.loginfo("Looking for ODrives...")

        self.SERIAL_NUMS = [
            35593293288011,                  # Left, 0
            35623406809166,                  # Middle, 1
            35563278839886]                  # Right, 2

        self.odrvs = [
            None,
            None,
            None]

        # Get ODrives
        done_signal = Event(None)

        def discovered_odrv(obj):
            print("Found odrive with sn: {}".format(obj.serial_number))
            if obj.serial_number in self.SERIAL_NUMS:
                self.odrvs[self.SERIAL_NUMS.index(obj.serial_number)] = obj
                print("ODrive is # {}".format(self.SERIAL_NUMS.index(obj.serial_number)))
            else:
                print("ODrive sn not found in list. New ODrive?")
            if not None in self.odrvs:
                done_signal.set()

        odrive.find_all("usb", None, discovered_odrv, done_signal, None, Logger(verbose=False))
        # Wait for ODrives
        try:
            done_signal.wait(timeout=120)
        finally:
            done_signal.set()

        # self.odrv0 = odrive.find_any()
        # # odrv1 = odrive.find_any()
        # # odrv2 = odrive.find_any()
        rospy.loginfo("Found ODrives")

        # Set left and right axis
        self.leftAxes = [self.odrvs[0].axis0, self.odrvs[0].axis1, self.odrvs[1].axis1]
        self.rightAxes = [self.odrvs[1].axis0, self.odrvs[2].axis0, self.odrvs[2].axis1]
        self.axes = self.leftAxes + self.rightAxes

        # Set axis state
        rospy.logdebug("Enabling Watchdog")
        for ax in (self.leftAxes + self.rightAxes):
            ax.watchdog_feed()
            ax.config.watchdog_timeout = 2
            ax.encoder.config.ignore_illegal_hall_state = True

        # Clear errors
        for odrv in self.odrvs:
            dump_errors(odrv, True)

        for ax in (self.leftAxes + self.rightAxes):
            ax.controller.vel_ramp_enable = True
            ax.requested_state = AXIS_STATE_CLOSED_LOOP_CONTROL
            ax.controller.config.control_mode = CTRL_MODE_VELOCITY_CONTROL

        # Sub to topic
        rospy.Subscriber('joy', Joy, self.vel_callback)

        # Set first watchdog
        self.timeout = timeout  # log error if this many seconds occur between received messages
        self.timer = rospy.Timer(rospy.Duration(self.timeout), self.watchdog_callback, oneshot=True)
        self.watchdog_fired = False

        # Init other variables
        self.last_msg_time = 0
        self.last_recv_time = 0
        self.next_wd_feed_time = 0

        rospy.loginfo("Ready for topic")
        rospy.spin()
예제 #22
0
from odrive.enums import *
from odrive.utils import start_liveplotter, dump_errors
import time

print("connecting")
# odrv1 = odrive.find_any(serial_number = "3762364A3137") #Connect ot Odrive1
print("odrv1 connected")
odrv0 = odrive.find_any(serial_number = "208037743548") #Connect ot Odrive0
print("odrv0 connected")



# Find a connected ODrive (this will block until you connect one)
# print("finding an odrive...")
# odrv0 = odrive.find_any()
dump_errors(odrv0,False)

# Find an ODrive that is connected on the serial port /dev/ttyUSB0
#odrv0 = odrive.find_any("serial:/dev/ttyUSB0")

#use the plotter to monitor the current and position
# start_liveplotter(lambda: [(odrv0.axis0.motor.current_control.Iq_measured*100),odrv0.axis0.encoder.count_in_cpr])
# start_liveplotter(lambda: [(odrv0.axis0.controller.input_pos),odrv0.axis0.encoder.pos_estimate])


time.sleep(2)
# EXAMPLE
# Read and print the voltage property
print("Bus voltage is " + str(odrv0.vbus_voltage) + "V")

예제 #23
0

def idle_wait():
    while odrv0.axis1.current_state != AXIS_STATE_IDLE:
        time.sleep(0.1)
    print(dump_errors(odrv0))


# Find a connected ODrive (this will block until you connect one)
print("finding an odrive...")

odrv0 = OdriveManager(path='/dev/ttySC0',
                      serial_number='336B31643536').find_odrive()
# odrv0 = odrive.find_any()

print(dump_errors(odrv0, True))
print(dump_errors(odrv0, True))

odrv0.axis1.requested_state = AXIS_STATE_IDLE
odrv0.axis1.controller.config.control_mode = CTRL_MODE_CURRENT_CONTROL
odrv0.axis1.requested_state = AXIS_STATE_CLOSED_LOOP_CONTROL

# Find an ODrive that is connected on the serial port /dev/ttyUSB0
#odrv0 = odrive.find_any("serial:/dev/ttyUSB0")

odrv0.axis1.motor.config.current_control_bandwidth = 20
odrv0.axis1.encoder.config.bandwidth = 100
odrv0.axis1.motor.current_control.p_gain = 0.3
odrv0.axis1.motor.current_control.i_gain = 0
odrv0.axis1.motor.current_control.final_v_beta = 0.1  # Voltage Ramp Rate
예제 #24
0
def wait_and_exit_on_error(ax):
    while ax.current_state != AXIS_STATE_IDLE:
        time.sleep(0.1)
    if ax.error != errors.axis.ERROR_NONE:
        dump_errors(odrv, True)
        exit()
예제 #25
0
# for odrv in odrives:
#     print(odrv.serial_number)
#     if odrv.serial_number == "208037743548":
#         odrv_YZ = odrv
#     elif odrv.serial_number == "3762364A3137":
#         odrv_X = odrv
#     else:
#         print("Found unkown odrive")
print("finding YZ odrive...")
odrv_YZ = odrive.find_any(serial_number="208037743548")

print("finding X odrive...")
odrv_X = odrive.find_any(serial_number="3762364A3137")

print("Found, prexisting errors:")
dump_errors(odrv_YZ, True)
dump_errors(odrv_X, True)

# Generic config
# odrv_YZ.config.enable_brake_resistor = True
odrv_YZ.config.brake_resistance = 0.4690000116825104

# odrv_X.config.enable_brake_resistor = True
odrv_X.config.brake_resistance = 0.4690000116825104

# Individual setup
# Z SETUP
odrv_YZ.axis0.motor.config.resistance_calib_max_voltage = 5.0
odrv_YZ.axis0.controller.config.pos_gain = 20.0
odrv_YZ.axis0.controller.config.vel_gain = 0.16
odrv_YZ.axis0.controller.config.vel_integrator_gain = 0.32
예제 #26
0
 def loco_dump_errors(self):
     dump_errors(odrv1, True)
예제 #27
0
 def clear_errors(self):
     dump_errors(self._odrv, True)
예제 #28
0
def idle_wait():
    while odrv0.axis1.current_state != AXIS_STATE_IDLE:
        time.sleep(0.1)
    print(dump_errors(odrv0))
예제 #29
0
if __name__ == '__main__':

    try:
        odrive.find_any().reboot()
        sleep(2)
        pass
    except:
        pass
    
    drv = Odrive()

    drv.axis0.requested_state = 3 #CALIBRATION
    sleep(15)
    
    ut.dump_errors(drv.od)
    # print(drv.enc0.config.cpr)
    # print(drv.od.axis0.motor.config.pole_pairs)
    drv.axis0.requested_state = 8 
    # sleep(1)
    # for i in range(1):
    #     drv.pos0 = 0
    #     sleep(3)
    #     drv.pos0 = 5
    #     sleep(3)
    #     #ut.dump_errors(drv.od)

    drv.axis1.requested_state = 3 #CALIBRATION
    sleep(15)
    
    ut.dump_errors(drv.od)
예제 #30
0
from __future__ import print_function

import odrive
from odrive.tests import *
from odrive.utils import dump_errors
from odrive.enums import *
from odrive.utils import start_liveplotter
import time

print("finding an odrive...")
odrv = odrive.find_any()
#axis = odrv.axis0
dump_errors(odrv, True)
exit
예제 #31
0
 def dig_dump_errors(self):
     dump_errors(odrv0, True)