"not implemented" when reading parameter in 0.5.3

Hi! I just updated both my firmware and odrivetool both to 0.5.3 (from 0.4.11), Odrive is v3.6 56V. After fixing several other issues I am stuck with this one: my UART ASCII command to read a parameter r axis0.encoder.is_ready returns not implemented instead of boolean true/false (in my Python code).

I’ve looked at all the migration tips in release files but do not see any changes in encoder/is_ready parameter and it can be read nicely using command line odrivetool (returns False).

The connection via Python script itself seems to be fine as the command r bus_voltage returns a value. So I am out of ideas where to look next?

the code I’m using to send command and read the result (cmd is the command ending with a newline):

import serial
...
ser = serial.Serial()
ser.port = port
ser.baudrate = 115200
ser.timeout = 0.1 # read timeout
ser.write_timeout = 0.1
...
cmd_bytes = cmd.encode('ascii')
ser.write(cmd_bytes)
response = ser.readline()
response = ser.decode('ascii').rstrip()

I wonder if this might be related:

  • found a thread in github where some other parameter gets “not implemented” response but this seems to be related to a self-compiled version

I am using Ubuntu 20.04, Python 3.8, Intel NUC PC computer. UART ASCII connection using FTDI cable, using GPIO 1 and 2.

UPDATE: this is not specific to the axis0.encoder.is_ready parameter but looks like a general issue as r config.gpio2_mode will also return not implemented while r axis1.error returns 0d :roll_eyes:

2 updates.

  1. I flashed the odrive with 0.5.1 and 0.5.2 and both of them behave the same, except instead of returning not implemented as in 0.5.3 older versions return invalid property. Could this help to debug the source of the problem?
  2. The problem only occurs when the system is running on ROS (e.g., the motors are working). If I just write a plain python code as in the post above and execute it as is, then it works fine. But when executed in a ROS control loop, it fails with the above errors.

My system is based on ROS and worked well using 0.4 branch and I have no special configuration on ODrive. Is there some kind of initialization or setup that is required in 0.5.x that I am missing (cannot find any on migration docs). Also the use case is so plain, I cannot see why it fails.

Curious. I will forward this onto the appropriate parties.

When I run r axis0.encoder.is_ready and r config.gpio2_mode in a screen session (screen /dev/ttyS0 115200 in my case) they both return a valid value (4 and 0 in my case).

Maybe there’s some other ROS component that accesses the same serial port? When in doubt connect the RX/TX lines of the FTDI cable and see if it echoes back the expected command.

r axis1.error does indeed return 0d instead of 0, I’ll note that down to fix for the next release.

2 Likes

An update. There are probably several issues. But I managed to figure out that w axis0.motor.config.motor_type 0 UART ASCII command will cause the problem and wrote a script to reproduce it:

import serial 
import odrive
import time

port = '/dev/odrive0'

ser = serial.Serial()
ser.port = port
ser.baudrate = 115200
ser.timeout = 0.1 # read timeout
ser.write_timeout = 0.1

ser.__enter__()

def cmd_to_bytes_and_send(cmd):
    print("SENDING:", cmd)
    cmd_formatted = '{}\n'.format(cmd)
    cmd_bytes = cmd_formatted.encode('ascii')
    ser.write(cmd_bytes)
    
def read_back_and_print():
    line = ser.readline()
    line = line.decode('ascii').rstrip()
    print("READBACK:", line)
    
if __name__ == "__main__":
    cmd = "r axis0.encoder.is_ready"
    print("CMD", cmd)
    
    cmd_bytes = cmd_to_bytes_and_send(cmd)
    read_back_and_print()
    
    r_cmd = "r axis0.motor.config.motor_type"
    cmd_to_bytes_and_send(r_cmd)
    read_back_and_print()

    ############ bad command here #####################3    
    bad_cmd = "w axis0.motor.config.motor_type 0"
    cmd_to_bytes_and_send(bad_cmd)
    
    # you will get back "not implemented"
    r_cmd = "r axis0.motor.config.motor_type"
    cmd_to_bytes_and_send(r_cmd)
    read_back_and_print()
    
    for i in range(5):
        r_cmd = "r axis0.motor.config.motor_type"
        cmd_to_bytes_and_send(r_cmd)
        read_back_and_print()

The output will be:

CMD r axis0.encoder.is_ready
SENDING: r axis0.encoder.is_ready
READBACK: 0
SENDING: r axis0.motor.config.motor_type
READBACK: 0
SENDING: w axis0.motor.config.motor_type 0
SENDING: r axis0.motor.config.motor_type
READBACK: not implemented
SENDING: r axis0.motor.config.motor_type
READBACK: 0
SENDING: r axis0.motor.config.motor_type
READBACK: 0
SENDING: r axis0.motor.config.motor_type
READBACK: 0
SENDING: r axis0.motor.config.motor_type
READBACK: 0
SENDING: r axis0.motor.config.motor_type
READBACK: 0 

First read after writing w axis0.motor.config.motor_type 0 causes the “not implemented” response no matter what the read command is. Most other parameters write well and do not have this issue. I assume just ignoring the first read command gets me past this, but it looks like it really is not implemented, meaning the write command has no effect.

While I could configure this one and save the configuration to odrive (although it will be painful) I do not see how to perform calibration when axis.requested_state = AXIS_STATE_FULL_CALIBRATION_SEQUENCE crashes my system with the same “not implemented” return message. It means that I am not able to calibrate my system?

PS! When I connect the RX/TX lines of the FTDI cable then it echoes back the expected commands, so not a cabling problem.

Have you tried inputting these commands manually e.g. with putty (windows) or picocom (linux)?

Yes, of course. They work as expected. But as I am using ASCII protocol over UART then there is little to do with this knowledge. I also checked for noise as @Samuel suggested. Are those really unimplemented in ASCII protocol or am I doing something wrong?

If they work when you type them manually, then they can’t be unimplemented in the protocol, right?

more likely, they are not implemented by whatever arduino library you are using.

I am not using any library, but sending the ASCII command as bytes directly to GPIO pins at ODrive using FTDI 3V USB->UART cable

The not implemented errors turned out to be a regression from 0.5.2 to 0.5.3 due to slight differences between compilers. I pushed a workaround to the fw-v0.5.4 branch.

You can follow the instructions here to compile the firmware. Once you have the .elf file you can flash it with odrivetool dfu [path-to-elf-file].

2 Likes

Super! Thanks @Samuel , I’ll try it! Do you know if this only affected those variables that returned “not implemented” or may there be any other silent fails too? I configured one robot manually using odrivetool and wonder if there might be surprises in navigation commands etc too or it only happens when I get this “not implemented” message?

Thanks! Reporting back that “not implemented” error is gone in 0.5.4 branch! :partying_face:

In my case, I needed to use .hex file to flash the drive with odrivetool dfu [file].

Thank you for a quick fix!

1 Like

It was an issue with a scanf code that wasn’t implemented in that compiler (only used in ASCII), so we don’t expect that to cause other fails.