From ff3c3723f5053964fbbfc180d9f6f3c72db8dd96 Mon Sep 17 00:00:00 2001 From: Ian Goh Date: Sun, 6 Jun 2021 10:59:34 +0800 Subject: [PATCH 01/11] Changed wether to whether --- docs/developer-guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/developer-guide.md b/docs/developer-guide.md index 62b542a0..360baaea 100644 --- a/docs/developer-guide.md +++ b/docs/developer-guide.md @@ -113,7 +113,7 @@ To customize the compile time parameters, copy or rename the file `Firmware/tup. __CONFIG_BOARD_VERSION__: The board version you're using. Can be `v3.1`, `v3.2`, `v3.3`, `v3.4-24V`, `v3.4-48V`, `v3.5-24V`, `v3.5-48V`, etc. Check for a label on the upper side of the ODrive to find out which version you have. Some ODrive versions don't specify the voltage: in that case you can read the value of the main capacitors: 120uF are 48V ODrives, 470uF are 24V ODrives. -__CONFIG_DEBUG__: Defines wether debugging will be enabled when compiling the firmware; specifically the `-g -gdwarf-2` flags. Note that printf debugging will only function if your tup.config specifies the `USB_PROTOCOL` or `UART_PROTOCOL` as stdout and `DEBUG_PRINT` is defined. See the IDE specific documentation for more information. +__CONFIG_DEBUG__: Defines whether debugging will be enabled when compiling the firmware; specifically the `-g -gdwarf-2` flags. Note that printf debugging will only function if your tup.config specifies the `USB_PROTOCOL` or `UART_PROTOCOL` as stdout and `DEBUG_PRINT` is defined. See the IDE specific documentation for more information. You can also modify the compile-time defaults for all `.config` parameters. You will find them if you search for `AxisConfig`, `MotorConfig`, etc. From 8286849e343a6959746cf25ea24eeebe162d222c Mon Sep 17 00:00:00 2001 From: Aaron de los Santos Date: Mon, 7 Jun 2021 15:20:01 -0700 Subject: [PATCH 02/11] Change variable name offset to phase_offset The encoder documentation page has been updated to reflect the renaming of encoder.config.offset to encoder.config.phase_offset --- docs/encoders.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/encoders.md b/docs/encoders.md index f01426e4..988c6080 100644 --- a/docs/encoders.md +++ b/docs/encoders.md @@ -20,7 +20,7 @@ In the `odrivetool`, type `.requested_state = AXIS_STATE_ENCODER_OFFSET_CA To verify everything went well, check the following variables: * `.error` should be 0. - * `.encoder.config.offset` - This should print a number, like -326 or 1364. + * `.encoder.config.phase_offset` - This should print a number, like -326 or 1364. * `.encoder.config.direction` - This should print 1 or -1. ### Encoder with index signal From 49a51802647f08dabc47fd375125d957cc660c21 Mon Sep 17 00:00:00 2001 From: Paul Guenette Date: Thu, 10 Jun 2021 23:05:32 -0400 Subject: [PATCH 03/11] Make can protocol arbitration ID clearer --- docs/can-protocol.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/can-protocol.md b/docs/can-protocol.md index 00a6a553..b73d725e 100644 --- a/docs/can-protocol.md +++ b/docs/can-protocol.md @@ -21,6 +21,17 @@ At its most basic, the CAN Simple frame looks like this: To understand how the Node ID and Command ID interact, let's look at an example +The 11-bit Arbitration ID is setup as follows: + +`can_id = axis_id << 5 | cmd_id` + +For example, an Axis ID of `0x01` with a command of `0x0C` would be result in `0x2C`: + +`0x01 << 5 | 0x0C = 0x2C` + +### Interoperability with CANopen +You can deconflict with CANopen like this: + `odrv0.axis0.can_node_id = 0x010` - Reserves messages 0x200 through 0x21F `odrv0.axis1.can_node_id = 0x018` - Reserves messages 0x300 through 0x31F From 64a6ddd1012a8b71cf03612497519eaccc296f74 Mon Sep 17 00:00:00 2001 From: Paul Guenette Date: Thu, 10 Jun 2021 23:06:17 -0400 Subject: [PATCH 04/11] Update can-protocol.md --- docs/can-protocol.md | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/docs/can-protocol.md b/docs/can-protocol.md index b73d725e..514f5afe 100644 --- a/docs/can-protocol.md +++ b/docs/can-protocol.md @@ -29,19 +29,6 @@ For example, an Axis ID of `0x01` with a command of `0x0C` would be result in `0 `0x01 << 5 | 0x0C = 0x2C` -### Interoperability with CANopen -You can deconflict with CANopen like this: - -`odrv0.axis0.can_node_id = 0x010` - Reserves messages 0x200 through 0x21F -`odrv0.axis1.can_node_id = 0x018` - Reserves messages 0x300 through 0x31F - -It may not be obvious, but this allows for some compatibility with CANOpen. Although the address space 0x200 and 0x300 correspond to receive PDO base addresses, we can guarantee they will not conflict if all CANopen node IDs are >= 32. E.g.: - -CANopen nodeID = 35 = 0x23 -Receive PDO 0x200 + nodeID = 0x223, which does not conflict with the range [0x200 : 0x21F] - -Be careful that you don't assign too many nodeIDs per PDO group. Four CAN Simple nodes (32*4) is all of the available address space of a single PDO. If the bus is strictly ODrive CAN Simple nodes, a simple sequential Node ID assignment will work fine. - ### Messages CMD ID | Name | Sender | Signals | Start byte | Signal Type | Bits | Factor | Offset | Byte Order @@ -96,3 +83,19 @@ odrv0.can.config.baud_rate = 500000 odrv0.save_configuration() odrv0.reboot() ``` + +--- + +### Interoperability with CANopen +You can deconflict with CANopen like this: + +`odrv0.axis0.can_node_id = 0x010` - Reserves messages 0x200 through 0x21F +`odrv0.axis1.can_node_id = 0x018` - Reserves messages 0x300 through 0x31F + +It may not be obvious, but this allows for some compatibility with CANOpen. Although the address space 0x200 and 0x300 correspond to receive PDO base addresses, we can guarantee they will not conflict if all CANopen node IDs are >= 32. E.g.: + +CANopen nodeID = 35 = 0x23 +Receive PDO 0x200 + nodeID = 0x223, which does not conflict with the range [0x200 : 0x21F] + +Be careful that you don't assign too many nodeIDs per PDO group. Four CAN Simple nodes (32*4) is all of the available address space of a single PDO. If the bus is strictly ODrive CAN Simple nodes, a simple sequential Node ID assignment will work fine. + From 2f36b095c55de7cd078f62fc844ed26a96e00176 Mon Sep 17 00:00:00 2001 From: Paul Guenette Date: Thu, 10 Jun 2021 23:06:42 -0400 Subject: [PATCH 05/11] Update can-protocol.md --- docs/can-protocol.md | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/docs/can-protocol.md b/docs/can-protocol.md index 514f5afe..9979fad8 100644 --- a/docs/can-protocol.md +++ b/docs/can-protocol.md @@ -9,6 +9,24 @@ ODrive currently supports the following CAN baud rates: * 500 kbps * 1000 kbps +--- +## Configuring ODrive for CAN +Configuration of the CAN parameters should be done via USB before putting the device on the bus. + +To set the desired baud rate, use `.can.config.baud_rate = `. + +Each axis looks like a separate node on the bus. Thus, they both have the two properties `can_node_id` and `can_node_id_extended`. The node ID can be from 0 to 63 (0x3F) inclusive, or, if extended CAN IDs are used, from 0 to 16777215 (0xFFFFFF). If you want to connect more than one ODrive on a CAN bus, you must set different node IDs for the second ODrive or they will conflict and crash the bus. + +### Example Configuration + +``` +odrv0.axis0.config.can_node_id = 3 +odrv0.axis1.config.can_node_id = 1 +odrv0.can.config.baud_rate = 500000 +odrv0.save_configuration() +odrv0.reboot() +``` + --- ## Transport Protocol We've implemented a very basic CAN protocol that we call "CAN Simple" to get users going with ODrive. This protocol is sufficiently abstracted that it is straightforward to add other protocols such as CANOpen, J1939, or Fibre over ISO-TP in the future. Unfortunately, implementing those protocols is a lot of work, and we wanted to give users a way to control ODrive's basic functions via CAN sooner rather than later. @@ -66,24 +84,6 @@ CMD ID | Name | Sender | Signals | Start byte | Signal Type | Bits | Factor | Of \*\* Note: These CANOpen messages are reserved to avoid bus collisions with CANOpen devices. They are not used by CAN Simple. \*\*\* Note: These messages can be sent to either address on a given ODrive board. ---- -## Configuring ODrive for CAN -Configuration of the CAN parameters should be done via USB before putting the device on the bus. - -To set the desired baud rate, use `.can.config.baud_rate = `. - -Each axis looks like a separate node on the bus. Thus, they both have the two properties `can_node_id` and `can_node_id_extended`. The node ID can be from 0 to 63 (0x3F) inclusive, or, if extended CAN IDs are used, from 0 to 16777215 (0xFFFFFF). If you want to connect more than one ODrive on a CAN bus, you must set different node IDs for the second ODrive or they will conflict and crash the bus. - -### Example Configuration - -``` -odrv0.axis0.config.can_node_id = 3 -odrv0.axis1.config.can_node_id = 1 -odrv0.can.config.baud_rate = 500000 -odrv0.save_configuration() -odrv0.reboot() -``` - --- ### Interoperability with CANopen From de77a698b6b2f8583a76534e8189b5dcb1a4a7d0 Mon Sep 17 00:00:00 2001 From: Paul Guenette Date: Wed, 16 Jun 2021 21:37:07 -0400 Subject: [PATCH 06/11] Update control.md --- docs/control.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/control.md b/docs/control.md index 886d7772..10aab174 100644 --- a/docs/control.md +++ b/docs/control.md @@ -6,6 +6,8 @@ The motor controller is a cascaded style position, velocity and current control Each stage of the control loop is a variation on a [PID controller](https://en.wikipedia.org/wiki/PID_controller). A PID controller is a mathematical model that can be adapted to control a wide variety of systems. This flexibility is essential as it allows the ODrive to be used to control all kinds of mechanical systems. +* Note: The controller has been updated to use `torque` in Newton-meters instead of current at the "system" level. There is a `torque_constant` parameter which converts between torque and current, after which the rest of this explanation still holds. + ### Position loop: The position controller is a P loop with a single proportional gain. ```text From a593a0016c4fbc1d01a0c41b895416bcf347c5ef Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Wed, 16 Jun 2021 20:45:42 -0700 Subject: [PATCH 07/11] lift control modes docs into its own sidebar doc --- docs/_data/index.yaml | 4 +- docs/control-modes.md | 100 +++++++++++++++++++++++++++++++++++++++ docs/getting-started.md | 101 ++++------------------------------------ 3 files changed, 111 insertions(+), 94 deletions(-) create mode 100644 docs/control-modes.md diff --git a/docs/_data/index.yaml b/docs/_data/index.yaml index f0bee327..91724d03 100644 --- a/docs/_data/index.yaml +++ b/docs/_data/index.yaml @@ -9,11 +9,13 @@ sections: url: / - title: ODrive Tool url: /odrivetool + - title: Control Modes + url: /control-modes - title: Parameters & Commands url: /commands - title: Encoders url: /encoders - - title: Control & Tuning + - title: Control Structure & Tuning url: /control - title: Troubleshooting url: /troubleshooting diff --git a/docs/control-modes.md b/docs/control-modes.md new file mode 100644 index 00000000..a1473558 --- /dev/null +++ b/docs/control-modes.md @@ -0,0 +1,100 @@ + +The default control mode is unfiltered position control in the absolute encoder reference frame. You may wish to use a controlled trajectory instead. Or you may wish to control position in a circular frame to allow continuous rotation forever without growing the numeric value of the setpoint too large. + +You may also wish to control velocity (directly or with a ramping filter). +You can also directly control the current of the motor, which is proportional to torque. + +- [Filtered position control](#filtered-position-control) +- [Trajectory control](#trajectory-control) +- [Circular position control](#circular-position-control) +- [Velocity control](#velocity-control) +- [Ramped velocity control](#ramped-velocity-control) +- [Torque control](#torque-control) + + +### Filtered position control +Asking the ODrive controller to go as hard as it can to raw setpoints may result in jerky movement. Even if you are using a planned trajectory generated from an external source, if that is sent at a modest frequency, the ODrive may chase each stair in the incoming staircase in a jerky way. In this case, a good starting point for tuning the filter bandwidth is to set it to one half of your setpoint command rate. + +You can use the second order position filter in these cases. +Set the filter bandwidth: `axis.controller.config.input_filter_bandwidth = 2.0` [1/s]
+Activate the setpoint filter: `axis.controller.config.input_mode = INPUT_MODE_POS_FILTER`.
+You can now control the velocity with `axis.controller.input_pos = 1` [turns]. + +![secondOrderResponse](secondOrderResponse.PNG)
+Step response of a 1000 to 0 position input with a filter bandwidth of 1.0 [/sec]. + +### Trajectory control +See the **Usage** section for usage details.
+This mode lets you smoothly accelerate, coast, and decelerate the axis from one position to another. With raw position control, the controller simply tries to go to the setpoint as quickly as possible. Using a trajectory lets you tune the feedback gains more aggressively to reject disturbance, while keeping smooth motion. + +![Taptraj](TrapTrajPosVel.PNG)
+In the above image blue is position and orange is velocity. + +#### Parameters +``` +..trap_traj.config.vel_limit = +..trap_traj.config.accel_limit = +..trap_traj.config.decel_limit = +..controller.config.inertia = +``` + +`vel_limit` is the maximum planned trajectory speed. This sets your coasting speed.
+`accel_limit` is the maximum acceleration in turns / sec^2
+`decel_limit` is the maximum deceleration in turns / sec^2
+`controller.config.inertia` is a value which correlates acceleration (in turns / sec^2) and motor torque. It is 0 by default. It is optional, but can improve response of your system if correctly tuned. Keep in mind this will need to change with the load / mass of your system. + +All values should be strictly positive (>= 0). + +Keep in mind that you must still set your safety limits as before. It is recommended you set these a little higher ( > 10%) than the planner values, to give the controller enough control authority. +``` +..motor.config.current_lim = +..controller.config.vel_limit = +``` + +#### Usage +Make sure you are in position control mode. To activate the trajectory module, set the input mode to trajectory: +``` +axis.controller.config.input_mode = INPUT_MODE_TRAP_TRAJ +``` + +Simply send a position command to execute the move: +``` +..controller.input_pos = +``` + +Use the `move_incremental` function to move to a relative position. +To set the goal relative to the current actual position, use `from_goal_point = False` +To set the goal relative to the previous destination, use `from_goal_point = True` +``` +..controller.move_incremental(pos_increment, from_goal_point) +``` + +You can also execute a move with the [appropriate ascii command](ascii-protocol.md#motor-trajectory-command). + +### Circular position control + +To enable Circular position control, set `axis.controller.config.circular_setpoints = True` + +This mode is useful for continuous incremental position movement. For example a robot rolling indefinitely, or an extruder motor or conveyor belt moving with controlled increments indefinitely. +In the regular position mode, the `input_pos` would grow to a very large value and would lose precision due to floating point rounding. + +In this mode, the controller will try to track the position within only one turn of the motor. Specifically, `input_pos` is expected in the range `[0, 1)`. If the `input_pos` is incremented to outside this range (say via step/dir input), it is automatically wrapped around into the correct value. +Note that in this mode `encoder.pos_circular` is used for feedback instead of `encoder.pos_estimate`. + +If you try to increment the axis with a large step in one go that exceeds `1` turn, the motor will go to the same angle around the wrong way. This is also the case if there is a large disturbance. If you have an application where you would like to handle larger steps, you can use a larger circular range. Set `controller.config.circular_setpoints_range = N`. Choose N to give you an appropriate circular space for your application. + +### Velocity control +Set `axis.controller.config.control_mode = CONTROL_MODE_VELOCITY_CONTROL`.
+You can now control the velocity with `axis.controller.input_vel = 1` [turn/s]. + +### Ramped velocity control +Set `axis.controller.config.control_mode = CONTROL_MODE_VELOCITY_CONTROL`.
+Set the velocity ramp rate (acceleration): `axis.controller.config.vel_ramp_rate = 0.5` [turn/s^2]
+Activate the ramped velocity mode: `axis.controller.config.input_mode = INPUT_MODE_VEL_RAMP`.
+You can now control the velocity with `axis.controller.input_vel = 1` [turn/s]. + +### Torque control +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`. diff --git a/docs/getting-started.md b/docs/getting-started.md index 0b09783e..13d3fa59 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -14,11 +14,13 @@ permalink: / - [Downloading and Installing Tools](#downloading-and-installing-tools) - [Firmware](#firmware) - [Start `odrivetool`](#start-odrivetool) +- [Debugging](#debugging) - [Configure M0](#configure-m0) - [Position control of M0](#position-control-of-m0) - [Other control modes](#other-control-modes) - [Watchdog Timer](#watchdog-timer) - [What's next?](#whats-next) +- [Upgrading from 0.4.12](#upgrading-from-0412) @@ -282,101 +284,14 @@ The default control mode is unfiltered position control in the absolute encoder You may also wish to control velocity (directly or with a ramping filter). You can also directly control the current of the motor, which is proportional to torque. -- [Filtered position control](#filtered-position-control) -- [Trajectory control](#trajectory-control) -- [Circular position control](#circular-position-control) -- [Velocity control](#velocity-control) -- [Ramped velocity control](#ramped-velocity-control) -- [Torque control](#torque-control) +- [Filtered position control](control-modes.md#filtered-position-control) +- [Trajectory control](control-modes.md#trajectory-control) +- [Circular position control](control-modes.md#circular-position-control) +- [Velocity control](control-modes.md#velocity-control) +- [Ramped velocity control](control-modes.md#ramped-velocity-control) +- [Torque control](control-modes.md#torque-control) -### Filtered position control -Asking the ODrive controller to go as hard as it can to raw setpoints may result in jerky movement. Even if you are using a planned trajectory generated from an external source, if that is sent at a modest frequency, the ODrive may chase each stair in the incoming staircase in a jerky way. In this case, a good starting point for tuning the filter bandwidth is to set it to one half of your setpoint command rate. - -You can use the second order position filter in these cases. -Set the filter bandwidth: `axis.controller.config.input_filter_bandwidth = 2.0` [1/s]
-Activate the setpoint filter: `axis.controller.config.input_mode = INPUT_MODE_POS_FILTER`.
-You can now control the velocity with `axis.controller.input_pos = 1` [turns]. - -![secondOrderResponse](secondOrderResponse.PNG)
-Step response of a 1000 to 0 position input with a filter bandwidth of 1.0 [/sec]. - -### Trajectory control -See the **Usage** section for usage details.
-This mode lets you smoothly accelerate, coast, and decelerate the axis from one position to another. With raw position control, the controller simply tries to go to the setpoint as quickly as possible. Using a trajectory lets you tune the feedback gains more aggressively to reject disturbance, while keeping smooth motion. - -![Taptraj](TrapTrajPosVel.PNG)
-In the above image blue is position and orange is velocity. - -#### Parameters -``` -..trap_traj.config.vel_limit = -..trap_traj.config.accel_limit = -..trap_traj.config.decel_limit = -..controller.config.inertia = -``` - -`vel_limit` is the maximum planned trajectory speed. This sets your coasting speed.
-`accel_limit` is the maximum acceleration in turns / sec^2
-`decel_limit` is the maximum deceleration in turns / sec^2
-`controller.config.inertia` is a value which correlates acceleration (in turns / sec^2) and motor torque. It is 0 by default. It is optional, but can improve response of your system if correctly tuned. Keep in mind this will need to change with the load / mass of your system. - -All values should be strictly positive (>= 0). - -Keep in mind that you must still set your safety limits as before. It is recommended you set these a little higher ( > 10%) than the planner values, to give the controller enough control authority. -``` -..motor.config.current_lim = -..controller.config.vel_limit = -``` - -#### Usage -Make sure you are in position control mode. To activate the trajectory module, set the input mode to trajectory: -``` -axis.controller.config.input_mode = INPUT_MODE_TRAP_TRAJ -``` - -Simply send a position command to execute the move: -``` -..controller.input_pos = -``` - -Use the `move_incremental` function to move to a relative position. -To set the goal relative to the current actual position, use `from_goal_point = False` -To set the goal relative to the previous destination, use `from_goal_point = True` -``` -..controller.move_incremental(pos_increment, from_goal_point) -``` - -You can also execute a move with the [appropriate ascii command](ascii-protocol.md#motor-trajectory-command). - -### Circular position control - -To enable Circular position control, set `axis.controller.config.circular_setpoints = True` - -This mode is useful for continuous incremental position movement. For example a robot rolling indefinitely, or an extruder motor or conveyor belt moving with controlled increments indefinitely. -In the regular position mode, the `input_pos` would grow to a very large value and would lose precision due to floating point rounding. - -In this mode, the controller will try to track the position within only one turn of the motor. Specifically, `input_pos` is expected in the range `[0, 1)`. If the `input_pos` is incremented to outside this range (say via step/dir input), it is automatically wrapped around into the correct value. -Note that in this mode `encoder.pos_circular` is used for feedback instead of `encoder.pos_estimate`. - -If you try to increment the axis with a large step in one go that exceeds `1` turn, the motor will go to the same angle around the wrong way. This is also the case if there is a large disturbance. If you have an application where you would like to handle larger steps, you can use a larger circular range. Set `controller.config.circular_setpoints_range = N`. Choose N to give you an appropriate circular space for your application. - -### Velocity control -Set `axis.controller.config.control_mode = CONTROL_MODE_VELOCITY_CONTROL`.
-You can now control the velocity with `axis.controller.input_vel = 1` [turn/s]. - -### Ramped velocity control -Set `axis.controller.config.control_mode = CONTROL_MODE_VELOCITY_CONTROL`.
-Set the velocity ramp rate (acceleration): `axis.controller.config.vel_ramp_rate = 0.5` [turn/s^2]
-Activate the ramped velocity mode: `axis.controller.config.input_mode = INPUT_MODE_VEL_RAMP`.
-You can now control the velocity with `axis.controller.input_vel = 1` [turn/s]. - -### Torque control -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`. - ## Watchdog Timer Each axis has a configurable watchdog timer that can stop the motors if the control connection to the ODrive is interrupted. From 738f603f86a8ba1a7bab6911f4720349d51894a2 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Wed, 16 Jun 2021 20:59:25 -0700 Subject: [PATCH 08/11] make it clear that 22nF is recommended on halls. --- docs/hoverboard.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/hoverboard.md b/docs/hoverboard.md index ec568fe3..12027f57 100644 --- a/docs/hoverboard.md +++ b/docs/hoverboard.md @@ -19,7 +19,7 @@ You may wire the motor phases in any order into a motor connector on the ODrive, | Green | Z | | Black | GND | -Note: In order to be compatible with encoder inputs, the ODrive doesn't have any filtering capacitors on the pins where the hall sensors connect. Therefore to get a reliable hall signal, it is recommended that you add some filter capacitors to these pins. You can see instructions [here](https://discourse.odriverobotics.com/t/encoder-error-error-illegal-hall-state/1047/7?u=madcowswe). +Note: In order to be compatible with encoder inputs, the ODrive doesn't have any filtering capacitors on the pins where the hall sensors connect. Therefore to get a reliable hall signal, it is recommended that you add some filter capacitors to these pins. We recommend about 22nF between each signal pin and GND. You can see instructions [here](https://discourse.odriverobotics.com/t/encoder-error-error-illegal-hall-state/1047/7?u=madcowswe). ### Hoverboard motor configuration From 58442e566eb03002faf8259ef70d9386dbe9e042 Mon Sep 17 00:00:00 2001 From: Samuel Sadok Date: Fri, 18 Jun 2021 08:44:06 +0200 Subject: [PATCH 09/11] fix missing version.c in CI --- .github/workflows/compile.yaml | 4 +++- Firmware/odrive-interface.yaml | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/compile.yaml b/.github/workflows/compile.yaml index a810ddb9..f9f6a146 100644 --- a/.github/workflows/compile.yaml +++ b/.github/workflows/compile.yaml @@ -91,7 +91,9 @@ jobs: cd ${{ github.workspace }}/Firmware echo "CONFIG_BOARD_VERSION=${{ matrix.board_version }}" >> tup.config echo "CONFIG_STRICT=true" >> tup.config - echo "CONFIG_DEBUG=${{ matrix.release }}" >> tup.config + echo "CONFIG_DEBUG=${{ matrix.debug }}" >> tup.config + mkdir -p autogen + python ../tools/odrive/version.py --output autogen/version.c tup init tup generate ./tup_build.sh diff --git a/Firmware/odrive-interface.yaml b/Firmware/odrive-interface.yaml index 42796c58..f628355b 100644 --- a/Firmware/odrive-interface.yaml +++ b/Firmware/odrive-interface.yaml @@ -700,7 +700,7 @@ interfaces: UNKNOWN_TORQUE: {doc: The motor controller did not get a valid torque input.} UNKNOWN_CURRENT_COMMAND: {doc: The current controller did not get a valid current setpoint. Maybe you didn't configure the controller correctly.} UNKNOWN_CURRENT_MEASUREMENT: {doc: The current controller did not get a valid current measurement.} - UNKNOWN_VBUS_VOLTAGE: {doc: The current controller did not get a valid `ODrive:vbus_voltage` measurement.} + UNKNOWN_VBUS_VOLTAGE: {doc: 'The current controller did not get a valid `ODrive:vbus_voltage` measurement.'} UNKNOWN_VOLTAGE_COMMAND: {doc: The current controller did not get a valid feedforward voltage setpoint.} UNKNOWN_GAINS: {doc: The current controller gains were not configured. Run motor calibration or set `config.phase_resistance` and `config.phase_inductance` manually.} CONTROLLER_INITIALIZING: {doc: Internal value used while the controller is not yet ready to generate PWM timings.} From 85296c40ce00458cecea865ae06a068fe4165cec Mon Sep 17 00:00:00 2001 From: Samuel Sadok Date: Fri, 18 Jun 2021 09:31:53 +0200 Subject: [PATCH 10/11] [CI] fix debian version check, fix macOS tup install --- .github/workflows/compile.yaml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/compile.yaml b/.github/workflows/compile.yaml index f9f6a146..1cf9ec56 100644 --- a/.github/workflows/compile.yaml +++ b/.github/workflows/compile.yaml @@ -36,13 +36,13 @@ jobs: run: | DEBIAN_VERSION="$(lsb_release --release --short)" echo Debian version: $DEBIAN_VERSION - if [ "$DEBIAN_VERSION" -gt 9 ]; then - sudo apt-get install gcc-arm-none-eabi - else + if [ "$DEBIAN_VERSION" == "16.04" ]; then # Ubuntu 16.04 (Debian 9) is on ARM GCC 4.9 which is too old for us sudo add-apt-repository ppa:team-gcc-arm-embedded/ppa sudo apt-get update sudo apt-get install gcc-arm-embedded + else + sudo apt-get install gcc-arm-none-eabi fi if ! (apt-cache search tup | grep "^tup - "); then @@ -58,7 +58,9 @@ jobs: if: startsWith(matrix.os, 'macOS-') run: | brew install armmbed/formulae/arm-none-eabi-gcc - brew install --cask osxfuse && brew install tup + brew install --cask osxfuse + # See https://github.com/osxfuse/osxfuse/issues/801#issuecomment-833419942 + brew install gromgit/fuse/tup-mac pip3 install PyYAML Jinja2 jsonschema From 0256229b229255551c183afc0df390111ae1fa52 Mon Sep 17 00:00:00 2001 From: Samuel Sadok Date: Fri, 18 Jun 2021 09:38:34 +0200 Subject: [PATCH 11/11] [CI] fix macOS install --- .github/workflows/compile.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/compile.yaml b/.github/workflows/compile.yaml index 1cf9ec56..d825bc73 100644 --- a/.github/workflows/compile.yaml +++ b/.github/workflows/compile.yaml @@ -58,8 +58,8 @@ jobs: if: startsWith(matrix.os, 'macOS-') run: | brew install armmbed/formulae/arm-none-eabi-gcc - brew install --cask osxfuse # See https://github.com/osxfuse/osxfuse/issues/801#issuecomment-833419942 + brew install --cask macfuse brew install gromgit/fuse/tup-mac pip3 install PyYAML Jinja2 jsonschema