Segway Ninebot S 10.5" Motors

I’ll apologize in advance if this is a basic question. This is my first time working with brushless motors. So I’m hoping my question is fairly basic in nature.

I’m using a 48V ODrive board, in conjunction with two 10.5" brushless motors scavenged from a Segway Ninebot S self balancing scooter. I’ve done several searches online, and am unable to find any detailed specifications for these motors, so I am afraid that I may not have the correct settings in my ODrive configuration for these motors.

At 24v DC, I have been successfully able to put both axes into AXIS_STATE_CLOSED_LOOP_CONTROL, and have been able to send vel_setpoint values to the motors and get them to spin. I have also attempted to send input_pos values to test moving the motors to specific positions, but the wheels do not move.

I’ve tried dumping the errors from the board, but don’t see anything out of sorts.

In [44]: dump_errors(odrv0)
axis0
  axis: no error
  motor: no error
  fet_thermistor: no error
  motor_thermistor: no error
  encoder: no error
  controller: no error
axis1
  axis: no error
  motor: no error
  fet_thermistor: no error
  motor_thermistor: no error
  encoder: no error
  controller: no error

This is what my motor configuration looks like.

In [45]: odrv0.axis0.motor
Out[45]: 
error = 0x0000 (int)
armed_state = 0 (int)
is_calibrated = True (bool)
current_meas_phB = -0.14581036567687988 (float)
current_meas_phC = 0.012346506118774414 (float)
DC_calib_phB = 1.1129567623138428 (float)
DC_calib_phC = -1.0598353147506714 (float)
phase_current_rev_gain = 0.012500000186264515 (float)
effective_current_lim = 10.0 (float)
current_control:
  p_gain = 0.04515017196536064 (float)
  i_gain = 22.528108596801758 (float)
  v_current_control_integral_d = 0.0 (float)
  v_current_control_integral_q = 0.0 (float)
  Ibus = 0.0 (float)
  final_v_alpha = 0.0 (float)
  final_v_beta = 0.0 (float)
  Id_setpoint = 0.0 (float)
  Iq_setpoint = 0.0 (float)
  Iq_measured = 0.0 (float)
  Id_measured = 0.0 (float)
  I_measured_report_filter_k = 1.0 (float)
  max_allowed_current = 30.375 (float)
  overcurrent_trip_level = 33.75 (float)
  acim_rotor_flux = 0.0 (float)
  async_phase_vel = 0.0 (float)
  async_phase_offset = 0.0 (float)
gate_driver:
  drv_fault = 0 (int)
timing_log:
  general = 44761 (int)
  adc_cb_i = 2654 (int)
  adc_cb_dc = 12866 (int)
  meas_r = 7934 (int)
  meas_l = 57326 (int)
  enc_calib = 6312 (int)
  idx_search = 27008 (int)
  foc_voltage = 7902 (int)
  foc_current = 64945 (int)
  spi_start = 55735 (int)
  sample_now = 17696 (int)
  spi_end = 13318 (int)
config:
  pre_calibrated = True (bool)
  pole_pairs = 15 (int)
  calibration_current = 20.0 (float)
  resistance_calib_max_voltage = 4.0 (float)
  phase_inductance = 0.00045150172081775963 (float)
  phase_resistance = 0.22528108954429626 (float)
  torque_constant = 0.5168750286102295 (float)
  direction = -1 (int)
  motor_type = 0 (int)
  current_lim = 40.0 (float)
  current_lim_margin = 8.0 (float)
  torque_lim = inf (float)
  inverter_temp_limit_lower = 100.0 (float)
  inverter_temp_limit_upper = 120.0 (float)
  requested_current_range = 24.0 (float)
  current_control_bandwidth = 100.0 (float)
  acim_slip_velocity = 14.706000328063965 (float)
  acim_gain_min_flux = 10.0 (float)
  acim_autoflux_min_Id = 10.0 (float)
  acim_autoflux_enable = False (bool)
  acim_autoflux_attack_gain = 10.0 (float)
  acim_autoflux_decay_gain = 1.0 (float)

I tried to follow the Hoverboard specific instructions as closely as possible. To test to see if I had the encoder details correct, I spun the wheel manually one full turn and looked at the axisX.encoder.shadow_count. It came back with the number 90, thus what is the value I used to set the axisX.encoder.config.cpr value.

Does anyone have any experience working with these motors, that could see if I am anywhere close to having the correct settings? I’m trying to build a ROS-based robot, and will need to publish transforms back to the navigation stack based on what data I can get back from the encoders.

Can you show us your odrv0.axis0.controller?

Sure. Here it is.

In [1]: odrv0.axis0.controller
Out[1]: 
error = 0x0000 (int)
input_pos = 0.0 (float)
input_vel = 0.0 (float)
input_torque = 0.0 (float)
pos_setpoint = 0.0 (float)
vel_setpoint = 0.0 (float)
torque_setpoint = 0.0 (float)
trajectory_done = True (bool)
vel_integrator_torque = 0.0 (float)
anticogging_valid = False (bool)
config:
  gain_scheduling_width = 10.0 (float)
  enable_vel_limit = True (bool)
  enable_current_mode_vel_limit = True (bool)
  enable_gain_scheduling = False (bool)
  enable_overspeed_error = True (bool)
  control_mode = 2 (int)
  input_mode = 1 (int)
  pos_gain = 1.0 (float)
  vel_gain = 0.9303750395774841 (float)
  vel_integrator_gain = 4.6518754959106445 (float)
  vel_limit = 10.0 (float)
  vel_limit_tolerance = 1.2000000476837158 (float)
  vel_ramp_rate = 10000.0 (float)
  torque_ramp_rate = 0.009999999776482582 (float)
  circular_setpoints = False (bool)
  circular_setpoint_range = 1.0 (float)
  homing_speed = 0.25 (float)
  inertia = 0.0 (float)
  axis_to_mirror = 255 (int)
  mirror_ratio = 1.0 (float)
  load_encoder_axis = 0 (int)
  input_filter_bandwidth = 2.0 (float)
  anticogging: ...
move_incremental(displacement: float, from_input_pos: bool)
start_anticogging_calibration()

Did you set controller.config.control_mode=CONTROL_MODE_POSITION_CONTROL before sending the input_pos?

1 Like