From 14149a173292207b4474e2f5229b310864472ab8 Mon Sep 17 00:00:00 2001 From: Drew Bednar Date: Tue, 24 Aug 2021 15:30:48 -0400 Subject: [PATCH] saving working hoverboard motor --- example/odrive-ctl.py | 62 ----------------- example/odrive_ctl.py | 154 ++++++++++++++++++++++++++++++++++++++++++ requirements.in | 2 +- 3 files changed, 155 insertions(+), 63 deletions(-) delete mode 100644 example/odrive-ctl.py create mode 100644 example/odrive_ctl.py diff --git a/example/odrive-ctl.py b/example/odrive-ctl.py deleted file mode 100644 index 0425cc9..0000000 --- a/example/odrive-ctl.py +++ /dev/null @@ -1,62 +0,0 @@ -from pathlib import Path, PurePath - -import click -import yaml - -# OPTIONS - -config_option = click.option( - '-c', - '--config', - default=PurePath(Path(__file__).parent, Path('odrive.yaml')), - type=Path, - help='A config file for the odrive. Defaults to odrive.yaml.' -) - - -@click.group() -def cli(): - pass - - -@cli.command('configure') -@config_option -def configure(**options): - """Configures an Odrive with a provided .yaml file of config values.""" - config_file = options['config'] - if not config_file.is_file(): - raise FileNotFoundError(f'No config file {config_file} found.') - print(options['config']) - - -class RoboWheelConfig: - """ - Class for configuring an Odrive axis. - """ - - # Motor KV - KV_RATING = 10.0 - - # min/max phase inductance of motor - MIN_PHASE_INDUCTANCE = 0.0 # ? - MAX_PHASE_INDUCTANCE = 0.001 # ? - - # Min/Max phase resistance of motor - MIN_PHASE_RESISTANCE = 0.0 # ? - MAX_PHASE_RESISTANCE = 2.5 # ? I think my motor is 1.7 ohm... - - ENCODER_PULSE_PER_REV = 3200.0 - ENCODER_COUNT_PER_REV = ENCODER_PULSE_PER_REV * 4 - - # Number of magnets in the motor divided by 2 - POLE_PAIR_COUNT = 27.0 - - # See https://docs.odriverobotics.com/hoverboard - RESISTANCE_CALIB_MAX_VOLTAGE = 4.0 # HB motors are larger with more resistance so he doubled the 2.0 default - REQUESTED_CURRENT_RANGE = 25.0 # lower values are more sensitive default was 60 - CURRENT_CONTROL_BANDWIDTH = 100.0 # Motors are also high inductance so the bandwidth to 100 from the default 1000 - TORQUE_CONSTANT = 8.27 / KV_RATING - - -if __name__ == "__main__": - cli() diff --git a/example/odrive_ctl.py b/example/odrive_ctl.py new file mode 100644 index 0000000..5802b21 --- /dev/null +++ b/example/odrive_ctl.py @@ -0,0 +1,154 @@ +from pathlib import Path, PurePath + +import click +import odrive +import yaml + +# CONSTANTS +AXIS_STATE_UNDEFINED = 0 +AXIS_STATE_IDLE = 1 +AXIS_STATE_STARTUP_SEQUENCE = 2 +AXIS_STATE_FULL_CALIBRATION_SEQUENCE = 3 +AXIS_STATE_MOTOR_CALIBRATION = 4 +AXIS_STATE_SENSORLESS_CONTROL = 5 +AXIS_STATE_ENCODER_INDEX_SEARCH = 6 +AXIS_STATE_ENCODER_OFFSET_CALIBRATION = 7 +AXIS_STATE_CLOSED_LOOP_CONTROL = 8 + +INPUT_MODE_VEL_RAMP = 2 + +# OPTIONS + +config_option = click.option( + '-c', + '--config', + default=PurePath(Path(__file__).parent, Path('odrive.yaml')), + type=Path, + help='A config file for the odrive. Defaults to odrive.yaml.' +) + + +@click.group() +def cli(): + pass + + +@cli.command('config-encoder') +@config_option +def config_encoder(**options): + """Configures an Odrive with a provided .yaml file of config values.""" + odrv0 = odrive.find_any() + odrv0.axis0.encoder.config.calib_range = 0.05 + odrv0.axis0.requested_state = AXIS_STATE_ENCODER_OFFSET_CALIBRATION + # Set negative to reverse index search direction + odrv0.axis1.encoder.config.calib_range = 0.05 + odrv0.axis1.requested_state = AXIS_STATE_ENCODER_OFFSET_CALIBRATION + print("You're motor encoder should be configured.") + return 0 + + +class RoboWheelConfig: + """ + Class for configuring an Odrive axis. + """ + + # Motor KV + KV_RATING = 10.0 + + # min/max phase inductance of motor + MIN_PHASE_INDUCTANCE = 0.0 # ? + MAX_PHASE_INDUCTANCE = 0.001 # ? + + # Min/Max phase resistance of motor + MIN_PHASE_RESISTANCE = 0.0 # ? + MAX_PHASE_RESISTANCE = 2.5 # ? I think my motor is 1.7 ohm... + + ENCODER_COUNT_PER_REV = 3200.0 + + # Number of magnets in the motor divided by 2 + POLE_PAIR_COUNT = 15.0 + + # See https://docs.odriverobotics.com/hoverboard + RESISTANCE_CALIB_MAX_VOLTAGE = 6.0 # HB motors are larger with more resistance so he doubled the 2.0 default + REQUESTED_CURRENT_RANGE = 35.0 # lower values are more sensitive default was 60 + CURRENT_CONTROL_BANDWIDTH = 1000.0 # Motors are also high inductance so the bandwidth to 100 from the default 1000 + TORQUE_CONSTANT = 8.27 / KV_RATING + CALIBRATION_CURRENT = 2 + ENABLE_BRAKE_RESISTOR = True + + +# Encoder steps +""" +odrv0.config.enable_brake_resistor = True # Using included 2ohm resistor +odrv0.axis0.motor.config.calibration_current = 2 # highest integer value where I heard the square wave was 4 +odrv0.axis0.motor.config.pole_pairs = 15 +odrv0.axis0.motor.config.resistance_calib_max_voltage = 6 # motor config still worked with this set to 6 +odrv0.axis0.motor.config.requested_current_range = 35 # 35 was the lowest value that produced and audible square wave. +odrv0.axis0.motor.config.current_control_bandwidth = 100.0 +odrv0.axis0.motor.config.torque_constant = 8.27 / 10 # KV 10 +odrv0.axis1.motor.config.calibration_current = 2 # highest integer value where I heard the square wave was 4 +odrv0.axis1.motor.config.pole_pairs = 15 +odrv0.axis1.motor.config.resistance_calib_max_voltage = 6 # motor config still worked with this set to 6 +odrv0.axis1.motor.config.requested_current_range = 35 # 35 was the lowest value that produced and audible square wave. +odrv0.axis1.motor.config.current_control_bandwidth = 100.0 +odrv0.axis1.motor.config.torque_constant = 8.27 / 10 # KV 10 + +# encoder +odrv0.axis0.encoder.config.mode = ENCODER_MODE_INCREMENTAL +odrv0.axis0.encoder.config.cpr = 3200 +odrv0.axis0.encoder.config.bandwidth = 1000 +odrv0.axis1.encoder.config.mode = ENCODER_MODE_INCREMENTAL +odrv0.axis1.encoder.config.cpr = 3200 +odrv0.axis1.encoder.config.bandwidth = 1000 + +odrv0.axis0.controller.config.input_mode = INPUT_MODE_VEL_RAMP +odrv0.axis0.controller.config.control_mode = CONTROL_MODE_VELOCITY_CONTROL +odrv0.axis0.controller.config.pos_gain = 1 +odrv0.axis0.controller.config.vel_gain = 0.002 * odrv0.axis0.motor.config.torque_constant * odrv0.axis0.encoder.config.cpr +odrv0.axis0.controller.config.vel_integrator_gain = 0.01 * odrv0.axis0.motor.config.torque_constant * odrv0.axis0.encoder.config.cpr +odrv0.axis0.controller.config.vel_limit = 5 +odrv0.axis1.controller.config.input_mode = INPUT_MODE_VEL_RAMP +odrv0.axis1.controller.config.control_mode = CONTROL_MODE_VELOCITY_CONTROL +odrv0.axis1.controller.config.pos_gain = 1 +odrv0.axis1.controller.config.vel_gain = 0.002 * odrv0.axis1.motor.config.torque_constant * odrv0.axis1.encoder.config.cpr +odrv0.axis1.controller.config.vel_integrator_gain = 0.01 * odrv0.axis1.motor.config.torque_constant * odrv0.axis1.encoder.config.cpr +odrv0.axis1.controller.config.vel_limit = 5 + +# BREAK HERE +odrv0.save_configuration() +odrv0.reboot() + +odrv0.axis0.requested_state = AXIS_STATE_MOTOR_CALIBRATION + +dump_errors(odrv0) + +odrv0.axis1.requested_state = AXIS_STATE_MOTOR_CALIBRATION + +odrv0.axis0.motor.config.pre_calibrated = True +odrv0.axis1.motor.config.pre_calibrated = True + +# BREAK HERE +odrv0.save_configuration() +odrv0.reboot() + + +# Encoder +odrv0.axis0.encoder.config.calib_range = 0.05 +odrv0.axis0.requested_state = AXIS_STATE_ENCODER_OFFSET_CALIBRATION +odrv0.axis1.encoder.config.calib_range = 0.05 +odrv0.axis1.requested_state = AXIS_STATE_ENCODER_OFFSET_CALIBRATION + +# Movement +odrv0.axis0.requested_state = AXIS_STATE_CLOSED_LOOP_CONTROL +odrv0.axis1.requested_state = AXIS_STATE_CLOSED_LOOP_CONTROL +odrv0.axis0.controller.input_vel = 0.5 +odrv0.axis1.controller.input_vel = 0.5 +# Your motor should spin here +odrv0.axis0.controller.input_vel = 0 +odrv0.axis1.controller.input_vel = 0 +odrv0.axis0.requested_state = AXIS_STATE_IDLE +odrv0.axis1.requested_state = AXIS_STATE_IDLE +""" + +if __name__ == "__main__": + cli() diff --git a/requirements.in b/requirements.in index 15d4254..96c77d3 100644 --- a/requirements.in +++ b/requirements.in @@ -1,3 +1,3 @@ click==7.1.1 -odrive +odrive==0.5.2.post0 pyyaml \ No newline at end of file