Robot Arm, Battle Bots, and Trajectory Issues

I am currently using ODrives on several projects. for one, I bought a Fanuc LR Mate 100i which didn’t come with a controller. I rewired the internals to use an ODrive to run everything, and I’ve been working on a full fledged controller and programming system including a wireless controller with interface. It’s going well so far, I will certainly post in more detail when it is finished.

Also, I have two battle bots in progress using ODrives for the drive system. Again, I’ll post more detail when they’re finished. But here’s a prototype slapped together using wood, we measured a speed of over 30mph with this setup.

I’ve had a ton of fun with ODrives, and I’m not even close to being finished. I’ve toasted three boards and fixed like two and a half or them. So, here’s I currently have two issues I’m working on getting fixed. The first is not being able to use Trajectory mode. I’ve gotten it to work on this setup before, but currently every time I set control_mode=4, it automatically goes back to control_mode=3.

In [44]: odrv0.axis0
Out[44]:
error = 0x0000 (int)
step_dir_active = False (bool)
current_state = 8 (int)
requested_state = 0 (int)
loop_counter = 14759946 (int)
config:
  startup_motor_calibration = False (bool)
  startup_encoder_index_search = False (bool)
  startup_encoder_offset_calibration = True (bool)
  startup_closed_loop_control = False (bool)
  startup_sensorless_control = False (bool)
  enable_step_dir = False (bool)
  counts_per_step = 2.0 (float)
  step_gpio_pin = 1 (int)
  dir_gpio_pin = 2 (int)
  ramp_up_time = 0.4000000059604645 (float)
  ramp_up_distance = 12.566370964050293 (float)
  spin_up_current = 10.0 (float)
  spin_up_acceleration = 400.0 (float)
  spin_up_target_vel = 400.0 (float)
get_temp()
motor:
  error = 0x0000 (int)
  armed_state = 3 (int)
  is_calibrated = True (bool)
  current_meas_phB = 0.0411112904548645 (float)
  current_meas_phC = 0.07308828830718994 (float)
  DC_calib_phB = -0.5445712804794312 (float)
  DC_calib_phC = -1.3016663789749146 (float)
  phase_current_rev_gain = 0.012500000186264515 (float)
  current_control: ...
  gate_driver: ...
  timing_log: ...
  config: ...
controller:
  error = 0x0000 (int)
  pos_setpoint = 709.75 (float)
  vel_setpoint = 0.0 (float)
  vel_integrator_current = -0.057480763643980026 (float)
  current_setpoint = 0.0 (float)
  vel_ramp_target = 0.0 (float)
  vel_ramp_enable = False (bool)
  config: ...
  set_pos_setpoint(pos_setpoint: float, vel_feed_forward: float, current_feed_forward: float)
  set_vel_setpoint(vel_setpoint: float, current_feed_forward: float)
  set_current_setpoint(current_setpoint: float)
  move_to_pos(goal_point: float)
  start_anticogging_calibration()
encoder:
  error = 0x0000 (int)
  is_ready = True (bool)
  index_found = False (bool)
  shadow_count = 709 (int)
  count_in_cpr = 709 (int)
  interpolation = 0.5 (float)
  phase = -0.14398956298828125 (float)
  pos_estimate = 709.859375 (float)
  pos_cpr = 709.8594970703125 (float)
  hall_state = 3 (int)
  vel_estimate = 0.0 (float)
  config: ...
sensorless_estimator:
  error = 0x0000 (int)
  phase = 0.14302998781204224 (float)
  pll_pos = 0.05569663643836975 (float)
  vel_estimate = -2.947011947631836 (float)
  config: ...
trap_traj:
  config: ...

In [45]: odrv0.axis0.controller
Out[45]:
error = 0x0000 (int)
pos_setpoint = 709.75 (float)
vel_setpoint = 0.0 (float)
vel_integrator_current = 0.07490172237157822 (float)
current_setpoint = 0.0 (float)
vel_ramp_target = 0.0 (float)
vel_ramp_enable = False (bool)
config:
  control_mode = 3 (int)
  pos_gain = 50.0 (float)
  vel_gain = 0.00039999998989515007 (float)
  vel_integrator_gain = 0.0005000000237487257 (float)
  vel_limit = 23000.0 (float)
  vel_limit_tolerance = 1.2000000476837158 (float)
  vel_ramp_rate = 10000.0 (float)
  setpoints_in_cpr = False (bool)
set_pos_setpoint(pos_setpoint: float, vel_feed_forward: float, current_feed_forward: float)
set_vel_setpoint(vel_setpoint: float, current_feed_forward: float)
set_current_setpoint(current_setpoint: float)
move_to_pos(goal_point: float)
start_anticogging_calibration()

In [46]: odrv0.axis0.trap_traj
Out[46]:
config:
  vel_limit = 20000.0 (float)
  accel_limit = 5000.0 (float)
  decel_limit = 5000.0 (float)
  A_per_css = 0.0 (float)

It’s weird because as i said, Traptraj was working fine with this exact setup not too long ago. Anyway, the other issue is with loosing encoder pulses (I think). This happens on the prototype battle bot linked above, so it goes through a lot of hits and shock. as I drive around and hit into stuff at high speed, a motor will go slower: even when the vel_stpoints are set to exactly the same value. I programmed my transmitter to do a full calibration (requested_state=3) when I push a button, this fixes the issue, but it always comes back after maybe 7 minutes of playing. You’re cool if you made it this far into my pitiful paragraphs :stuck_out_tongue_winking_eye: .

1 Like

Very nice, can’t wait to see more about the robot arm, and that drift racer looks really fun.

How did your boards get toasted? Is there something we can do in terms of firmware protection features or protective cover, or otherwise that would have prevented it?

Yes please excuse us, the trajectory state behaves a bit different than the others. With all the other states, you write it and it sticks. With trajectory mode, it works like the following diagram. You would have the controller in mode 3, then send move_to_pos. The firmware will move the mode to trajectory control by itself, and back to pos mode when done.

trajectory_pos_state

I agree that this is a bit unclear, so in the future maybe we will move “trajectory is active” away from control_mode and to a separate flag (meaning you should leave it in pos control mode for trajectories). But for now, please use it as per the above state diagram.

1 Like

Thanks for the trajectory mode clarification. I don’t believe there has ever been any firmware issue that caused the Odrives to fail. I’m pretty sure it’s been metallic dust of some sort that gets on to them from the ground when they are in the bots, the things that seem to go wrong are the voltage regulators and occasionally the main chip, all of which I’ve replaced and have gotten the board running again. I ordered some conformal coating to spray the boards with to hopefully prevent that from happening again.

Fried microcontroller is usually caused by voltage spikes on the shared ground between the ODrive and the other side of the UART/stepdir/etc. This can happen if DC- (power ground) is shared between the ODrive and some other controller, which can get large currents or inductive current pulses on it.

Does that apply to you?

Not in this particular instance, the arduino running it uses the pins for 5v and ground, but that’s good to know for future reference for the robot arm.