CAN Interface Available for Testing

Champion! I appreciate the quick & awesome reply Towen. I’ll dig into this tonight & tomorrow and hopefully be able to report some progress.

I’m running it on an Arduino MKR 1010 with the Sandeep CAN library which is a bit different to the cansend utility.

Update: Thanks Towen, your feedback got me right on course. Got it up and running!!

Update 2: To help those who are using an arduino (I’m using the MKR 1010 Wifi) and Sandeeps CAN library here is the code I used:
#include <CAN.h>

CAN.beginPacket(0x7F7, 0, 1);
CAN.endPacket();

… and then use the reciever code example.

1 Like

I got my CAN network up and running and sending positions, however regardless of what settings I change it doesn’t seem to be using “Trajectory Control”. It just moves the same regardless of what settings I edit.

Is there a way to get it to use trajectory control via CAN?

If you are on one of the recent firmwares like v0.5.1 then you can set controller.config.input_mode=INPUT_MODE_TRAP_TRAJ which should do it?

1 Like

Towen you are a champion! I spent 2-3 hours today looking for a solution. I will try it tomorrow morning and report back with the results.

Thank you a hundred times over.

I ran the code and it provided the following error. I’m 99% sure I’m on v0.5.1 but when I check with odrv1.fw_version_major it returns 0.

odrv0.controller.config.input_mode=INPUT_MODE_TRAP_TRAJ

NameError: name ‘INPUT_MODE_TRAP_TRAJ’ is not defined

I’ll double check I am on the latest version but I just flashed it a few days ago.

Check that tools/odrive/enums.py contains the line
INPUT_MODE_TRAP_TRAJ = 5
Also check that you have a file called Firmware/odrive-interface.yaml It should mention trap_traj: TrapezoidalTrajectory somewhere.
If you don’t have that file, then you are NOT on rc-0.5.1.

I really don’t know what is going wrong.

I’m definitely running 0.5.1 and have loaded it from a mac and PC just to be safe and have the files listed. I’ve compiled it and also used the compiled version to no avail. I am stumped.

For the enums you have to run the rc ODrive tool from the tools folder.

cd ODrive/tools
./odrivetool

You’ll see some yellow text about it being the development tool and some new text with links to everything.

If you just run odrivetool from wherever, it’ll probably use the pip version which is the “master” version

I think the version might return 0.

1 Like

Thank you Wetmelon and Towen, I feel like I got stuck at every turn but you guys got me there in the end.

I might do a write up down the line to help some folks who might be in the same position as me.

Well… this just aint my week when it comes to odrive.

I got the new odrivetool up and running like a charm… on the old odrivetool I had the CAN bus sending positions. However now that I’ve moved to the new tool I can’t get the motor to move to position like it used to via the same messages sent via the CAN bus.

If I add some to the end it jerks however I think this has nothing to do with the “input_pos” command.
eg: 0xcc 00 00 00 00 00 05 00 00
eg; 0xcc 00 00 00 00 00 00 00 00

I’ve spent most of the day on this and making no progress… anyone able to through me a line?

I’ve dumped my config logs below to try and help :thinking:

Controller 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 = 3 (int)
input_mode = 5 (int)
pos_gain = 20.0 (float)
vel_gain = 0.1666666716337204 (float)
vel_integrator_gain = 0.3333333432674408 (float)
vel_limit = 5000.0 (float)
vel_limit_tolerance = 1.2000000476837158 (float)
vel_ramp_rate = 1.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 = 1 (int)
input_filter_bandwidth = 2.0 (float)
anticogging:
index = 0 (int)
pre_calibrated = False (bool)
calib_anticogging = False (bool)
calib_pos_threshold = 1.0 (float)
calib_vel_threshold = 1.0 (float)
cogging_ratio = 1.0 (float)
anticogging_enabled = True (bool)

Axis 1 Config
startup_motor_calibration = True (bool)
startup_encoder_index_search = False (bool)
startup_encoder_offset_calibration = False (bool)
startup_closed_loop_control = True (bool)
startup_sensorless_control = False (bool)
startup_homing = False (bool)
enable_step_dir = False (bool)
step_dir_always_on = False (bool)
turns_per_step = 0.0009765625 (float)
watchdog_timeout = 0.0 (float)
enable_watchdog = False (bool)
step_gpio_pin = 7 (int)
dir_gpio_pin = 8 (int)
calibration_lockin:
current = 10.0 (float)
ramp_time = 0.4000000059604645 (float)
ramp_distance = 3.1415927410125732 (float)
accel = 20.0 (float)
vel = 40.0 (float)
sensorless_ramp:
current = 10.0 (float)
ramp_time = 0.4000000059604645 (float)
ramp_distance = 3.1415927410125732 (float)
accel = 200.0 (float)
vel = 400.0 (float)
finish_distance = 100.0 (float)
finish_on_vel = True (bool)
finish_on_distance = False (bool)
finish_on_enc_idx = False (bool)
general_lockin:
current = 10.0 (float)
ramp_time = 0.4000000059604645 (float)
ramp_distance = 3.1415927410125732 (float)
accel = 20.0 (float)
vel = 40.0 (float)
finish_distance = 100.0 (float)
finish_on_vel = False (bool)
finish_on_distance = False (bool)
finish_on_enc_idx = False (bool)
can_node_id = 6 (int)
can_node_id_extended = False (bool)
can_heartbeat_rate_ms = 100 (int)

Have you upgraded the firmware, or just odrivetool?

Does it work if you set input_pos from the python shell via USB? (i.e., is this a CAN problem or something else?)

1 Like

Hey mate, thanks for your speedy reply!

  1. I’ve upgraded both the firmware & odrivetool. Do you know of a command I can run via USB to double check this? The only ones I know of are below:
    odrv0.fw_version_major = 0
    odrv0.fw_version_minor = 0
    odrv0.fw_version_revision = 0
    odrv0.fw_version_unreleased = 1

  2. It does work via set input pos via USB. However when I send the command via CAN I get no movement, so my guess is this is a CAN problem.

  3. Does anyone know where I can change the firmware version in the code? I’m looking for where I can edit the firmware version so I can triple check that the firmware has indeed updated properly. I’ve done edits to firmware before so I’m comfortable I’ve done it before, however I want to be 100% sure.

  4. However, I do know I’m connected via CAN because I get movement in this part of the CAN packet:

And when I then set “input_pos = 1” it will move to that position, and when it recieves the CAN message, it runs back to 0.0 (and I’ve tried many combinations of HEX in the first 4 bytes).

Hmm, it sounds as if maybe you are sending the wrong node ID?

Make sure that you have set axis.config.can_node_id, and that you are sending the same node ID in the packet.
0xcc decodes as node ID 6, is that right?

Try my CANSimple.py - I wrote it a while ago but I don’t think the protocol has changed - if it has, you should be able to see where to change it. Note that you need the python3-sortedcontainers package installed (for reasons of the GUI that I started writing on top of this) and you also need to have my own enums.py in the same directory.

2 Likes

Thanks Towen for the quick reply!

  1. Yes, the CAN ID is 6 generated from your code: ((3 << 5)+ 0x0C)

  2. Thank you for sharing your testing programs, however I’m running off an Arduino MKR 1010 so I won’t be able to use them.

I’m stumped on this one, I didn’t expect it to be as difficult to connect the CAN network.

Hm, it’s a shame you don’t also have a RPi or CANable or something to test with. I’ve never trusted Arduino. :joy:
Straight bare-metal GNU AVR-LIBC back when Arduino used Atmel AVRs was great, but Arduino itself puts so much abstraction in.

You could still use my code to generate message IDs for you to send (just print them instead of trying to send a CAN frame)

Maybe this is an endianness issue? The 11 bit message ID is more than 1 byte - are you treating it as one 16-bit integer or two 8-bit ones?
(this is where python’s struct.pack came in really handy for me :stuck_out_tongue_closed_eyes:)

1 Like

Thank for the reply Towen. I think the universe is sending me a message to step away from CAN for a minute, my arduino MKR died in a puff of smoke. I’ve never had that happen before and not sure why.

I think your on the money with getting something to test it with, I’ll order something to connect my PC so I can do some more rigorous testing.

Hi towen!

I’ve come to know, my ecu does not support RTR / SRR.
Is there any other option to make the ODrive stream the encoder position and measured current to the bus?

That’s actually something I’ve wanted to implement for some time now. I will look into adding it

1 Like

That would be awesome!

Its possible to specify only the Input Pos? What should I write into Vel FF and Torque FF?
image

I have take a look into can_simple.cpp and they seem not optional like in ASCII protocol:
image