From 32136b90c390b28002ec9532f8baceebebd84e57 Mon Sep 17 00:00:00 2001 From: Paul Guenette Date: Sun, 24 Oct 2021 14:52:05 -0400 Subject: [PATCH 1/7] Add Danfoss wiring page link to CAN guide --- docs/can-guide.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/can-guide.md b/docs/can-guide.md index 827d3635..e008e940 100644 --- a/docs/can-guide.md +++ b/docs/can-guide.md @@ -10,8 +10,12 @@ Borrowing from [Wikipeda](https://en.wikipedia.org/wiki/CAN_bus): In simple terms, CAN is a way of communicating between many devices over a single twisted pair of wires. The signal is transmitted as the difference in voltage between the two wires (differential signalling), which makes it very robust against noise. Instead of using a unique address (like I2C) or a select pin (like SPI), CAN *messages* have a unique ID that also acts as the priority. At the beginning of a message frame, all devices talk and read at the same time. As the message ID is transmitted, the lowest value "wins" and that message will be transmitted (ID **0** has the *highest* priority). All other devices will wait for the next chance to send. If two devices send the same message ID at the same time, they will conflict and a bus failure may occur. Make sure your devices can never send the same message ID at the same time! +See also this great article from Danfoss that quickly describes how to put together the wiring for a CAN bus https://danfosseditron.zendesk.com/hc/en-gb/articles/360042232992-CAN-bus-physical-layer + ![CAN picture](screenshots/CAN_Bus_Drawing.png) + + ## Why use CAN? CAN is convenient for its simple and robust Physical Layer (PHY) that requires only a twisted pair of wires and a 120ohm termination resistor at each end. It has low jitter and low latency, because there is no host computer. It is relatively fast (CAN 2.0b supports 1 Mbps). Messages are easy to configure and load with data. Transceivers and controllers are inexpensive and widely available, thanks to its use in automotive. @@ -131,4 +135,4 @@ Instead of manually writing values into the data, we can create a dictionary of The [CAN DBC Example](../tools/can_dbc_example.py) script shows you how this can be used. This is the recommended method of serializing and deserializing. -If you're using C++, then you can use the [CANHelpers](..firmware/communication/../../../Firmware/communication/can/can_helpers.hpp) single-header library to do this instead, although the DBC file isn't used. \ No newline at end of file +If you're using C++, then you can use the [CANHelpers](..firmware/communication/../../../Firmware/communication/can/can_helpers.hpp) single-header library to do this instead, although the DBC file isn't used. From 737690066500268a673e86faf3aa20cbb99716d9 Mon Sep 17 00:00:00 2001 From: Paul Guenette Date: Mon, 25 Oct 2021 01:52:35 -0400 Subject: [PATCH 2/7] current -> torque mode vel limit --- docs/control-modes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/control-modes.md b/docs/control-modes.md index a1473558..d896d6e1 100644 --- a/docs/control-modes.md +++ b/docs/control-modes.md @@ -97,4 +97,4 @@ You can now control the velocity with `axis.controller.input_vel = 1` [turn/s]. Set `axis.controller.config.control_mode = CONTROL_MODE_TORQUE_CONTROL`.
You can now control the torque with `axis.controller.input_torque = 0.1` [Nm]. -Note: If you exceed `vel_limit` in torque control mode, the current is reduced. To disable this, set `axis.controller.enable_current_mode_vel_limit = False`. +Note: If you exceed `vel_limit` in torque control mode, the current is reduced. To disable this, set `axis.controller.enable_torque_mode_vel_limit = False`. From 50562dd563d6b6f0598bf2313354603006ec0624 Mon Sep 17 00:00:00 2001 From: madewhatnow Date: Sat, 30 Oct 2021 18:45:01 -0700 Subject: [PATCH 3/7] Update to use axis0.controller.input_pos --- tools/odrive_demo.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/odrive_demo.py b/tools/odrive_demo.py index 38d2c69b..8ede3901 100755 --- a/tools/odrive_demo.py +++ b/tools/odrive_demo.py @@ -26,7 +26,7 @@ my_drive.axis0.requested_state = AXIS_STATE_CLOSED_LOOP_CONTROL print("Bus voltage is " + str(my_drive.vbus_voltage) + "V") # Or to change a value, just assign to the property -my_drive.axis0.controller.pos_setpoint = 3.14 +my_drive.axis0.controller.input_pos = 3.14 print("Position setpoint is " + str(my_drive.axis0.controller.pos_setpoint)) # And this is how function calls are done: @@ -38,7 +38,7 @@ t0 = time.monotonic() while True: setpoint = 4.0 * math.sin((time.monotonic() - t0)*2) print("goto " + str(int(setpoint))) - my_drive.axis0.controller.pos_setpoint = setpoint + my_drive.axis0.controller.input_pos = setpoint time.sleep(0.01) # Some more things you can try: From 8e9745a6528f737ef867871027fdd0f7faefd38f Mon Sep 17 00:00:00 2001 From: Aleksandr Date: Tue, 2 Nov 2021 14:50:35 +0300 Subject: [PATCH 4/7] Add version.c generation to dockerbuild and actions --- .github/actions/release-firmware/action.yml | 3 +++ Dockerfile | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/.github/actions/release-firmware/action.yml b/.github/actions/release-firmware/action.yml index 0ce949da..1cd85e7a 100644 --- a/.github/actions/release-firmware/action.yml +++ b/.github/actions/release-firmware/action.yml @@ -19,6 +19,9 @@ runs: cd ${{ github.workspace }}/Firmware + mkdir -p autogen + python ../tools/odrive/version.py --output autogen/version.c + echo "CONFIG_STRICT=true" > tup.config echo "CONFIG_BOARD_VERSION=${{ inputs.board_version }}" >> tup.config tup init diff --git a/Dockerfile b/Dockerfile index 06bdadf1..6e30b45e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,6 +17,10 @@ WORKDIR ODrive/Firmware # Must attach the firmware tree into the container CMD \ + # Regenerate autogen/version.c + mkdir -p autogen && \ + python ../tools/odrive/version.py \ + --output autogen/version.c && \ # Regenerate python interface python interface_generator_stub.py \ --definitions odrive-interface.yaml \ From 31e601ebedc76b27f8b0313a65a1b4030754d89c Mon Sep 17 00:00:00 2001 From: Aleksandr Date: Tue, 2 Nov 2021 15:23:42 +0300 Subject: [PATCH 5/7] Fix race condition in trap traj control --- Firmware/MotorControl/controller.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/MotorControl/controller.cpp b/Firmware/MotorControl/controller.cpp index 4149b30d..546847ed 100644 --- a/Firmware/MotorControl/controller.cpp +++ b/Firmware/MotorControl/controller.cpp @@ -209,7 +209,7 @@ bool Controller::update() { if (axis_->trap_traj_.t_ > axis_->trap_traj_.Tf_) { // Drop into position control mode when done to avoid problems on loop counter delta overflow config_.control_mode = CONTROL_MODE_POSITION_CONTROL; - pos_setpoint_ = input_pos_; + pos_setpoint_ = axis_->trap_traj_.Xf_; vel_setpoint_ = 0.0f; torque_setpoint_ = 0.0f; trajectory_done_ = true; From fb6a2356ea28cec3a31a50abcc010f32061d1702 Mon Sep 17 00:00:00 2001 From: Piotr Rak Date: Wed, 3 Nov 2021 20:33:17 +0100 Subject: [PATCH 6/7] Allow running dockerbuild.sh from other shells than bash directly. --- dockerbuild.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dockerbuild.sh b/dockerbuild.sh index acf77e9d..c9475564 100755 --- a/dockerbuild.sh +++ b/dockerbuild.sh @@ -1,3 +1,4 @@ +#!/usr/bin/env bash function cleanup { echo "Removing previous build artifacts" rm -rf build/ Firmware/autogen Firmware/build Firmware/.tup From 0121ccf2490f5f0664d26ac248601472157b5ee7 Mon Sep 17 00:00:00 2001 From: Paul Guenette Date: Mon, 15 Nov 2021 20:21:04 -0500 Subject: [PATCH 7/7] Add section on cyclic messages to can_protocol --- docs/can-protocol.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/can-protocol.md b/docs/can-protocol.md index ac396a0f..77008f45 100644 --- a/docs/can-protocol.md +++ b/docs/can-protocol.md @@ -84,6 +84,18 @@ All multibyte values are little endian (aka Intel format, aka least significant --- +### Cyclic Messages +Cyclic messages are sent by ODrive on a timer without a request. As of `fw0.5.4`, the Cyclic messsages are: + +ID | Name | Rate (ms) +--: | :-- | :-- +0x001 | ODrive Heartbeat Message | 100 +0x009 | Encoder Estimates | 10 + +These can be configured for each axis, see e.g. `axis.config.can`. + +--- + ### Interoperability with CANopen You can deconflict with CANopen like this: