My first Odrive! - no encoder yet, having issue with sensorless control


#1

Hi Odrive community!

I just got my Odrive yesterday and I’m eventually going to be working on a position control project, but for now I don’t have an encoder to use with my gimbal BLDC motor, so to start, I wanted to play with sensorless control. Well technically it does have an encoder but the encoder can only interface with SPI/I2C/PWM, but not AB/I pulse encoding. I hope to eventually update firmware to interface with this encoder through SPI.
Here is a link to the motor specs:

THE ISSUE:
Yesterday I was able to get some progress going with odrivetool on Ubuntu, and by the end of the day when I boot up the Odrive my motor slowly ramps up to what LOOKS close to my vel_setpoint, but then comes to a sudden stop as soon as it gets there, and won’t budge until a reboot. I say “as soon as it gets there” only because if I set a much faster vel_setpoint and reboot, it speeds up beyond where it had stopped before and stops once it gets to a speed that again LOOKS close to the new vel_setpoint. This behavior is consistent with whatever vel_setpoint I program as well as spin_up_acceleration. I’ve played with different controller.config.vel_gain and vel_integrator_gain values but I cannot change the behavior. On previous posts I saw that when people had this problem, it could be solved by correctly tuning the vel_gain/vel_integrator_gain, and also being very sure about the sensorless_estimator.pm_flux_linkage value.

HERE’S WHAT I’VE DONE:
odrv0.vbus_voltage
14.915258407592773 //Also tried with 20V, 24V and 12V to the board, same results
odrv0.axis0.motor.config.motor_type = MOTOR_TYPE_GIMBAL
odrv0.axis0.motor.config.pole_pairs = 11 //the motor is “configuration 24N22P” - 22 Magnets, 11 pole pairs
odrv0.config.brake_resistance = 0.6 //Using the provided 50W resistor, ohmeter measures 0.6 ohm
odrv0.axis0.motor.config.current_lim = 1 //Specs show motor rated for 1.2A
odrv0.axis0.motor.config.calibration_current = 1
odrv0.axis0.controller.config.vel_gain = 0.01
odrv0.axis0.controller.config.vel_integrator_gain = 0.05
odrv0.axis0.controller.config.control_mode = 2
odrv0.axis0.controller.vel_setpoint = 500
odrv0.axis0.sensorless_estimator.config.pm_flux_linkage = 5.51328895422 / (11*143) //Specs show KV = 143
odrv0.axis0.config.startup_motor_calibration = True
odrv0.axis0.config.startup_encoder_index_search = False
odrv0.axis0.config.startup_encoder_offset_calibration = False
odrv0.axis0.config.startup_closed_loop_control = False
odrv0.axis0.config.startup_sensorless_control = True
odrv0.save_configuration()
odrv0.reboot()
//Motor immediately turned ~60degrees counter clockwise (calibration?) then began ramping up quickly and abruptly stopped, there is some holding torque (harder to turn by hand than if it were powered off)
//So then I did this:
odrv0.axis0.error
64
odrv0.axis0.motor.error
128
odrv0.axis0.motor.is_calibrated
True
odrv0.axis0.motor.config.phase_resistance
0.0
odrv0.axis0.motor.config.phase_inductance
0.0
odrv0.axis0.motor.config.phase_resistance = 5.7 //measured with ohmeter as 5.7ohms - consistent for all 3 coils
odrv0.axis0.motor.config.phase_inductance = 0.0007 //Specs say “inductance: 0.7mH”
odrv0.axis0.controller.config.vel_integrator_gain = 0
odrv0.axis0.config.spin_up_acceleration = 30
odrv0.axis0.config.spin_up_target_vel = 500
odrv0.save_configuration()
odrv0.reboot()
//From here the motor does not do the initial 60degree turn, but immediately starts slowly ramping up speed (counterclockwise). All is stable until it reaches some speed that seems close to my set point (visually) then suddenly stops with holding torque. As I said above, this behavior is the same for multiple different vel_setpoints and it’s clear that it stops at different speeds depending on the vel_setpoint I give it. Also, I’m sure to mach the spin_up_target_vel with the vel_setpoint I give, but still the result is the same. And every time I reboot those errors are now zero:
odrv0.axis0.error
0
odrv0.axis0.motor
0

Has anyone else run into this issue? I’m pretty stuck :frowning: Any ideas or advice would be greatly appreciated!!!

I want to at least confirm that I can control the motor speed and direction with sensorless before I start messing around with the firmware, because it will be helpful for me to spin the motor in sensorless with a script in the firmware to confirm that I’m atleast compiling and uploading correctly.

Thank you so much for reading! I’m sorry it was a long one, but I wanted to give as much info as possible,
Evan


#2

I don’t think you will be able to run a gimbal motor in sensorless mode. Sensorless mode requires measuring the current accurately, and gimbal motors current range is usually around 2A max, and that’s very noisy with the default current sense shunt resistors.


#3

I see, that makes sense :frowning: Thank you for the reply!

I’m giving up on running it sensorless right now. As I mentioned in my post, I eventually want to drive the motor in position control using the AS5048A absolute encoder that is inside my gimbal motor. I found a pull request on the topic of adding SPI support for interfacing with AS5047P encoder (https://github.com/madcowswe/ODrive/pull/191) So I read the data sheet and that encoder’s SPI protocol is identical to AS5048A the one in my motor. I cloned the branch to my PC and I’m trying to compile and upload it into my Odrive, even if there are some bugs, to try and start playing with it. After reading the info on the firmware guide, I was able to install the dependencies for tup and arm-gcc etc. and I was able to build (make) the project successfully, but when trying to use sudo odrivetool dfu ~/Desktop/ODrive/Firmware/build/ODriveFirmware.hex, I’m having some issues. Specifically the error messages:
Erasing… done
Flashing… done
Verifying… done
Waiting for the device to reappear…
Traceback (most recent call last):
File “/usr/local/bin/odrivetool”, line 142, in
odrive.dfu.launch_dfu(args, logger, app_shutdown_token)
File “/usr/local/lib/python3.5/dist-packages/odrive/dfu.py”, line 454, in launch_dfu
update_device(device, firmware, logger, cancellation_token)
File “/usr/local/lib/python3.5/dist-packages/odrive/dfu.py”, line 417, in update_device
if do_backup_config:
UnboundLocalError: local variable ‘do_backup_config’ referenced before assignment

Do I have completely the wrong idea about this? Is it even possible to add SPI support to the Odrive by building a cloned project like this one and dfu it into the Odrive through USB?

I realize this question is off topic from the original question in this post. If you like I can just make another post for this question.

Thank you for your help,
Evan


#4

I was able to search the error message and find a solution, it was pretty simple in my case.

I just had to define the variable do_backup_config = False in dfu.py before any of the if statements that used the variable later on in the script. Seems like a simple scope issue. Either way it solved my problem and I was able to upload this new firmware !