Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 128 additions & 0 deletions ODrive/Gemini.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# Torque control, pole pair and current tweak

# 1. Reset configuration to a clean slate
odrv0.erase_configuration()

# Cap total board draw at 27A to protect 30A regulatory fuse (3A safety buffer)
odrv0.config.dc_max_positive_current = 27.0
# Max current allowed back into the battery pack during aggressive braking
odrv0.config.dc_max_negative_current = -20.0

# --- MOTOR CONFIGURATION (VEVOR 1800W / 2000W OPTIMIZED) ---
# Axis 0
odrv0.axis0.motor.config.pole_pairs = 4 # Correct Vevor magnet count
odrv0.axis0.motor.config.current_lim = 30.0 # Max allowed phase current for torque
odrv0.axis0.motor.config.calibration_current = 10.0
odrv0.axis0.motor.config.current_lim_margin = 12.0 # Isolates spikes from throwing a fault
odrv0.axis0.motor.config.requested_current_range = 45.0 # Gives shunt amps room to read
odrv0.axis0.motor.config.torque_constant = 0.0919 # Tidied precision (8.27 / 90 KV)
odrv0.axis0.motor.config.resistance_calib_max_voltage = 6.0
odrv0.axis0.motor.config.current_control_bandwidth = 100.0 # Low bandwidth stops sensor noise/saturation
odrv0.axis0.config.I_bus_hard_max = 20.0 # Max battery draw allowed for this single axis

# Axis 1
odrv0.axis1.motor.config.pole_pairs = 4
odrv0.axis1.motor.config.current_lim = 30.0
odrv0.axis1.motor.config.calibration_current = 10.0
odrv0.axis1.motor.config.current_lim_margin = 12.0
odrv0.axis1.motor.config.requested_current_range = 45.0
odrv0.axis1.motor.config.torque_constant = 0.0919
odrv0.axis1.motor.config.resistance_calib_max_voltage = 6.0
odrv0.axis1.motor.config.current_control_bandwidth = 100.0
odrv0.axis1.config.I_bus_hard_max = 20.0

# --- ENCODER CONFIGURATION (HALL SENSORS) ---
# Axis 0
odrv0.axis0.encoder.config.mode = ENCODER_MODE_HALL
odrv0.axis0.encoder.config.cpr = 24 # 4 Pole Pairs * 6 = 24
odrv0.axis0.encoder.config.ignore_illegal_hall_state = True
odrv0.axis0.encoder.config.calib_scan_distance = 150.0
odrv0.axis0.encoder.config.bandwidth = 100.0

# Axis 1
odrv0.axis1.encoder.config.mode = ENCODER_MODE_HALL
odrv0.axis1.encoder.config.cpr = 24
odrv0.axis1.encoder.config.ignore_illegal_hall_state = True
odrv0.axis1.encoder.config.calib_scan_distance = 150.0
odrv0.axis1.encoder.config.bandwidth = 100.0

# --- CONTROLLER CONFIGURATION (TORQUE MODE & GAINS) ---
# Axis 0
odrv0.axis0.controller.config.control_mode = CONTROL_MODE_TORQUE_CONTROL
odrv0.axis0.controller.config.pos_gain = 50.0
odrv0.axis0.controller.config.vel_gain = 0.1
odrv0.axis0.controller.config.vel_integrator_gain = 0.2
odrv0.axis0.controller.config.vel_limit = 85.0 # Hard RPM safety ceiling (~5200 RPM)
odrv0.axis0.controller.config.vel_ramp_rate = 30.0

# Axis 1
odrv0.axis1.controller.config.control_mode = CONTROL_MODE_TORQUE_CONTROL
odrv0.axis1.controller.config.pos_gain = 50.0
odrv0.axis1.controller.config.vel_gain = 0.1
odrv0.axis1.controller.config.vel_integrator_gain = 0.2
odrv0.axis1.controller.config.vel_limit = 85.0
odrv0.axis1.controller.config.vel_ramp_rate = 30.0

# Save and reboot
print("Saving configuration and rebooting... Reconnect your terminal in a moment.")
odrv0.save_configuration()
try:
odrv0.reboot()
except Exception:
pass


Phase 2: Live Calibration Setup

Wait for the ODrive to reboot and reconnect. Keep the wheels off the ground.
Python

print("Starting calibration sequence. Motors will beep and turn slowly...")
odrv0.axis0.requested_state = AXIS_STATE_FULL_CALIBRATION_SEQUENCE
odrv0.axis1.requested_state = AXIS_STATE_FULL_CALIBRATION_SEQUENCE

# WAIT until the motors finish moving completely before continuing!

Verify everything passed cleanly:
Python

dump_errors(odrv0)
print(f"Axis 0 Ready: {odrv0.axis0.encoder.is_ready} | Axis 1 Ready: {odrv0.axis1.encoder.is_ready}")

Phase 3: Lock and Commit (No More Calibrations)
Python

# Save current calibration state as permanent baseline
odrv0.axis0.motor.config.pre_calibrated = True
odrv0.axis0.encoder.config.pre_calibrated = True
odrv0.axis1.motor.config.pre_calibrated = True
odrv0.axis1.encoder.config.pre_calibrated = True

# Skip future startup calibrations and arm automatically on power-up
odrv0.axis0.config.startup_motor_calibration = False
odrv0.axis0.config.startup_encoder_offset_calibration = False
odrv0.axis0.config.startup_closed_loop_control = True

odrv0.axis1.config.startup_motor_calibration = False
odrv0.axis1.config.startup_encoder_offset_calibration = False
odrv0.axis1.config.startup_closed_loop_control = True

odrv0.save_configuration()
print("Calibration locked! System set to Motorcycle-Style Twist Torque Control.")

Phase 4: Inputs and Controls Configuration
Twist-Grip Analog Torque Mapping (GPIO 3 & 4)
Python

# Axis 0 Analog Input (GPIO 3)
odrv0.config.gpio3_analog_mapping.min = 0.0 # Twist grip at rest = 0.0 Nm (Coasting)
odrv0.config.gpio3_analog_mapping.max = 75.0 # Full twist = 75.0 Nm max acceleration torque
odrv0.config.gpio3_analog_mapping.endpoint = odrv0.axis0.controller._input_torque_property

# Axis 1 Analog Input (GPIO 4)
odrv0.config.gpio4_analog_mapping.min = 0.0
odrv0.config.gpio4_analog_mapping.max = 75.0
odrv0.config.gpio4_analog_mapping.endpoint = odrv0.axis1.controller._input_torque_property

odrv0.save_configuration()
print("Twist grip torque mapping complete! Good luck out on the track.")