From 1aa6e6704f7f86a8c28dbc9b9a89f3b5482ba3d6 Mon Sep 17 00:00:00 2001 From: Linus NEP <86525017+LinusNEP@users.noreply.github.com> Date: Mon, 8 May 2023 09:54:38 +0200 Subject: [PATCH] Delete ODrive Calibration directory --- ODrive Calibration/ODrive_calibration.py | 272 ------------------- ODrive Calibration/ODrive_calibration.tar.gz | Bin 5529 -> 0 bytes 2 files changed, 272 deletions(-) delete mode 100644 ODrive Calibration/ODrive_calibration.py delete mode 100644 ODrive Calibration/ODrive_calibration.tar.gz diff --git a/ODrive Calibration/ODrive_calibration.py b/ODrive Calibration/ODrive_calibration.py deleted file mode 100644 index 7aca43f..0000000 --- a/ODrive Calibration/ODrive_calibration.py +++ /dev/null @@ -1,272 +0,0 @@ - - -""" -These configurations is based on Austin Owens implementation: https://github.com/AustinOwens/robodog/blob/main/odrive/configs/odrive_hoverboard_config.py - -It was based on the hoverboard tutorial found on the Odrive Robotics website at: https://docs.odriverobotics.com/v/0.5.4/hoverboard.html - -""" - -import sys -import time -import math -import odrive -from odrive.enums import * -import fibre.libfibre -from fibre import Logger, Event -from odrive.utils import OperationAbortedException - - -class MotorConfig: - """ - Class for configuring an Odrive axis for a Hoverboard motor. - Only works with one Odrive at a time. - """ - - # Hoverboard Kv - HOVERBOARD_KV = 16.0 - - # Min/Max phase inductance of motor - MIN_PHASE_INDUCTANCE = 0 - MAX_PHASE_INDUCTANCE = 0.001 - - # Min/Max phase resistance of motor - MIN_PHASE_RESISTANCE = 0 - MAX_PHASE_RESISTANCE = 0.5 - - # Tolerance for encoder offset float - ENCODER_OFFSET_FLOAT_TOLERANCE = 0.05 - - def __init__(self, axis_num): - """ - Initalizes MotorConfig class by finding odrive, erase its - configuration, and grabbing specified axis object. - - :param axis_num: Which channel/motor on the odrive your referring to. - :type axis_num: int (0 or 1) - """ - - self.axis_num = axis_num - - # Connect to Odrive - print("Looking for ODrive...") - self._find_odrive() - print("Found ODrive.") - - def _find_odrive(self): - # connect to Odrive - self.odrv = odrive.find_any() - self.odrv_axis = getattr(self.odrv, "axis{}".format(self.axis_num)) - - def configure(self): - """ - Configures the odrive device for a hoverboard motor. - """ - - # Erase pre-exsisting configuration - print("Erasing pre-exsisting configuration...") - try: - self.odrv.erase_configuration() - except ChannelBrokenException: - pass - - self._find_odrive() - - # Standard 6.5 inch hoverboard hub motors have 30 permanent magnet - # poles, and thus 15 pole pairs - self.odrv_axis.motor.config.pole_pairs = 15 - - # Hoverboard hub motors are quite high resistance compared to the hobby - # aircraft motors, so we want to use a bit higher voltage for the motor - # calibration, and set up the current sense gain to be more sensitive. - # The motors are also fairly high inductance, so we need to reduce the - # bandwidth of the current controller from the default to keep it - # stable. - self.odrv_axis.motor.config.resistance_calib_max_voltage = 4 - self.odrv_axis.motor.config.requested_current_range = 25 - self.odrv_axis.motor.config.current_control_bandwidth = 100 - - # Estimated KV but should be measured using the "drill test", which can - # be found here: # https://discourse.odriverobotics.com/t/project-hoverarm/441 - self.odrv_axis.motor.config.torque_constant = 8.27 / self.HOVERBOARD_KV - - # Hoverboard motors contain hall effect sensors instead of incremental - # encorders - self.odrv_axis.encoder.config.mode = ENCODER_MODE_HALL - - # The hall feedback has 6 states for every pole pair in the motor. Since - # we have 15 pole pairs, we set the cpr to 15*6 = 90. - self.odrv_axis.encoder.config.cpr = 90 - - # Since hall sensors are low resolution feedback, we also bump up the - #offset calibration displacement to get better calibration accuracy. - self.odrv_axis.encoder.config.calib_scan_distance = 150 - - # Since the hall feedback only has 90 counts per revolution, we want to - # reduce the velocity tracking bandwidth to get smoother velocity - # estimates. We can also set these fairly modest gains that will be a - # bit sloppy but shouldn’t shake your rig apart if it’s built poorly. - # Make sure to tune the gains up when you have everything else working - # to a stiffness that is applicable to your application. - self.odrv_axis.encoder.config.bandwidth = 100 - self.odrv_axis.controller.config.pos_gain = 1 - self.odrv_axis.controller.config.vel_gain = 0.02 * self.odrv_axis.motor.config.torque_constant * self.odrv_axis.encoder.config.cpr - self.odrv_axis.controller.config.vel_integrator_gain = 0.1 * self.odrv_axis.motor.config.torque_constant * self.odrv_axis.encoder.config.cpr - self.odrv_axis.controller.config.vel_limit = 10 - - # Set in position control mode so we can control the position of the wheel - self.odrv_axis.controller.config.control_mode = CONTROL_MODE_POSITION_CONTROL - - # In the next step we are going to start powering the motor and so we - # want to make sure that some of the above settings that require a - # reboot are applied first. - print("Saving manual configuration and rebooting...") - self.odrv.save_configuration() - print("Manual configuration saved.") - try: - self.odrv.reboot() - except ChannelBrokenException: - pass - - self._find_odrive() - - input("Make sure the motor is free to move, then press enter...") - - print("Calibrating Odrive for hoverboard motor (you should hear a " "beep)...") - - self.odrv_axis.requested_state = AXIS_STATE_MOTOR_CALIBRATION - - # Wait for calibration to take place - time.sleep(10) - - if self.odrv_axis.motor.error != 0: - print("Error: Odrive reported an error of {} while in the state " - "AXIS_STATE_MOTOR_CALIBRATION. Printing out Odrive motor data for " - "debug:\n{}".format(self.odrv_axis.motor.error, - self.odrv_axis.motor)) - - sys.exit(1) - - if self.odrv_axis.motor.config.phase_inductance <= self.MIN_PHASE_INDUCTANCE or \ - self.odrv_axis.motor.config.phase_inductance >= self.MAX_PHASE_INDUCTANCE: - print("Error: After odrive motor calibration, the phase inductance " - "is at {}, which is outside of the expected range. Either widen the " - "boundaries of MIN_PHASE_INDUCTANCE and MAX_PHASE_INDUCTANCE (which " - "is between {} and {} respectively) or debug/fix your setup. Printing " - "out Odrive motor data for debug:\n{}".format(self.odrv_axis.motor.config.phase_inductance, - self.MIN_PHASE_INDUCTANCE, - self.MAX_PHASE_INDUCTANCE, - self.odrv_axis.motor)) - - sys.exit(1) - - if self.odrv_axis.motor.config.phase_resistance <= self.MIN_PHASE_RESISTANCE or \ - self.odrv_axis.motor.config.phase_resistance >= self.MAX_PHASE_RESISTANCE: - print("Error: After odrive motor calibration, the phase resistance " - "is at {}, which is outside of the expected range. Either raise the " - "MAX_PHASE_RESISTANCE (which is between {} and {} respectively) or " - "debug/fix your setup. Printing out Odrive motor data for " - "debug:\n{}".format(self.odrv_axis.motor.config.phase_resistance, - self.MIN_PHASE_RESISTANCE, - self.MAX_PHASE_RESISTANCE, - self.odrv_axis.motor)) - - sys.exit(1) - - # If all looks good, then lets tell ODrive that saving this calibration - # to persistent memory is OK - self.odrv_axis.motor.config.pre_calibrated = True - - # Check the alignment between the motor and the hall sensor. Because of - # this step you are allowed to plug the motor phases in random order and - # also the hall signals can be random. Just don’t change it after - # calibration. - print("Calibrating Odrive for encoder...") - self.odrv_axis.requested_state = AXIS_STATE_ENCODER_OFFSET_CALIBRATION - - # Wait for calibration to take place - time.sleep(30) - - if self.odrv_axis.encoder.error != 0: - print("Error: Odrive reported an error of {} while in the state " - "AXIS_STATE_ENCODER_OFFSET_CALIBRATION. Printing out Odrive encoder " - "data for debug:\n{}".format(self.odrv_axis.encoder.error, - self.odrv_axis.encoder)) - - sys.exit(1) - - # If offset_float isn't 0.5 within some tolerance, or its not 1.5 within - # some tolerance, raise an error - if not ((self.odrv_axis.encoder.config.offset_float > 0.5 - self.ENCODER_OFFSET_FLOAT_TOLERANCE and \ - self.odrv_axis.encoder.config.offset_float < 0.5 + self.ENCODER_OFFSET_FLOAT_TOLERANCE) or \ - (self.odrv_axis.encoder.config.offset_float > 1.5 - self.ENCODER_OFFSET_FLOAT_TOLERANCE and \ - self.odrv_axis.encoder.config.offset_float < 1.5 + self.ENCODER_OFFSET_FLOAT_TOLERANCE)): - print("Error: After odrive encoder calibration, the 'offset_float' " - "is at {}, which is outside of the expected range. 'offset_float' " - "should be close to 0.5 or 1.5 with a tolerance of {}. Either " - "increase the tolerance or debug/fix your setup. Printing out " - "Odrive encoder data for debug:\n{}".format(self.odrv_axis.encoder.config.offset_float, - self.ENCODER_OFFSET_FLOAT_TOLERANCE, - self.odrv_axis.encoder)) - - sys.exit(1) - - # If all looks good, then lets tell ODrive that saving this calibration - # to persistent memory is OK - self.odrv_axis.encoder.config.pre_calibrated = True - - print("Saving calibration configuration and rebooting...") - self.odrv.save_configuration() - print("Calibration configuration saved.") - try: - self.odrv.reboot() - except ChannelBrokenException: - pass - - self._find_odrive() - - print("Odrive configuration finished.") - - def mode_idle(self): - """ - Puts the motor in idle (i.e. can move freely). - """ - - self.odrv_axis.requested_state = AXIS_STATE_IDLE - - def mode_close_loop_control(self): - """ - Puts the motor in closed loop control. - """ - - self.odrv_axis.requested_state = AXIS_STATE_CLOSED_LOOP_CONTROL - - def move_input_pos(self, angle): - """ - Puts the motor at a certain angle. - - :param angle: Angle you want the motor to move. - :type angle: int or float - """ - - self.odrv_axis.controller.input_pos = angle/360.0 - -if __name__ == "__main__": - hb_motor_config = MotorConfig(axis_num = 0) - hb_motor_config.configure() - - print("CONDUCTING MOTOR TEST") - print("Placing motor in close loop control. If you move motor, motor will " - "resist you.") - hb_motor_config.mode_close_loop_control() - - # Go from 0 to 360 degrees in increments of 30 degrees - for angle in range(0, 390, 30): - print("Setting motor to {} degrees.".format(angle)) - hb_motor_config.move_input_pos(angle) - time.sleep(5) - - print("Placing motor in idle. If you move motor, motor will " - "move freely") - hb_motor_config.mode_idle() - diff --git a/ODrive Calibration/ODrive_calibration.tar.gz b/ODrive Calibration/ODrive_calibration.tar.gz deleted file mode 100644 index fc661dbdb15804d002e89726689a13f5031dc172..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5529 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