mirror of
https://github.com/odriverobotics/ODrive.git
synced 2026-08-18 01:18:52 +08:00
Merge branch 'master' into fw-v0.5.3
This commit is contained in:
@@ -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
|
||||
# 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
|
||||
|
||||
|
||||
@@ -91,7 +93,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
|
||||
|
||||
|
||||
@@ -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.}
|
||||
|
||||
@@ -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
|
||||
|
||||
+32
-18
@@ -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 `<odrv>.can.config.baud_rate = <value>`.
|
||||
|
||||
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.
|
||||
@@ -21,15 +39,13 @@ 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
|
||||
|
||||
`odrv0.axis0.can_node_id = 0x010` - Reserves messages 0x200 through 0x21F
|
||||
`odrv0.axis1.can_node_id = 0x018` - Reserves messages 0x300 through 0x31F
|
||||
The 11-bit Arbitration ID is setup as follows:
|
||||
|
||||
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.:
|
||||
`can_id = axis_id << 5 | cmd_id`
|
||||
|
||||
CANopen nodeID = 35 = 0x23
|
||||
Receive PDO 0x200 + nodeID = 0x223, which does not conflict with the range [0x200 : 0x21F]
|
||||
For example, an Axis ID of `0x01` with a command of `0x0C` would be result in `0x2C`:
|
||||
|
||||
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.
|
||||
`0x01 << 5 | 0x0C = 0x2C`
|
||||
|
||||
### Messages
|
||||
|
||||
@@ -69,19 +85,17 @@ CMD ID | Name | Sender | Signals | Start byte | Signal Type | Bits | Factor | Of
|
||||
\*\*\* 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 `<odrv>.can.config.baud_rate = <value>`.
|
||||
### Interoperability with CANopen
|
||||
You can deconflict with CANopen like this:
|
||||
|
||||
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.
|
||||
`odrv0.axis0.can_node_id = 0x010` - Reserves messages 0x200 through 0x21F
|
||||
`odrv0.axis1.can_node_id = 0x018` - Reserves messages 0x300 through 0x31F
|
||||
|
||||
### Example Configuration
|
||||
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.
|
||||
|
||||
```
|
||||
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()
|
||||
```
|
||||
|
||||
@@ -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]<br>
|
||||
Activate the setpoint filter: `axis.controller.config.input_mode = INPUT_MODE_POS_FILTER`.<br>
|
||||
You can now control the velocity with `axis.controller.input_pos = 1` [turns].
|
||||
|
||||
<br>
|
||||
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.<br>
|
||||
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.
|
||||
|
||||
<br>
|
||||
In the above image blue is position and orange is velocity.
|
||||
|
||||
#### Parameters
|
||||
```
|
||||
<odrv>.<axis>.trap_traj.config.vel_limit = <Float>
|
||||
<odrv>.<axis>.trap_traj.config.accel_limit = <Float>
|
||||
<odrv>.<axis>.trap_traj.config.decel_limit = <Float>
|
||||
<odrv>.<axis>.controller.config.inertia = <Float>
|
||||
```
|
||||
|
||||
`vel_limit` is the maximum planned trajectory speed. This sets your coasting speed.<br>
|
||||
`accel_limit` is the maximum acceleration in turns / sec^2<br>
|
||||
`decel_limit` is the maximum deceleration in turns / sec^2<br>
|
||||
`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.
|
||||
```
|
||||
<odrv>.<axis>.motor.config.current_lim = <Float>
|
||||
<odrv>.<axis>.controller.config.vel_limit = <Float>
|
||||
```
|
||||
|
||||
#### 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:
|
||||
```
|
||||
<odrv>.<axis>.controller.input_pos = <Float>
|
||||
```
|
||||
|
||||
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`
|
||||
```
|
||||
<odrv>.<axis>.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`.<br>
|
||||
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`.<br>
|
||||
Set the velocity ramp rate (acceleration): `axis.controller.config.vel_ramp_rate = 0.5` [turn/s^2]<br>
|
||||
Activate the ramped velocity mode: `axis.controller.config.input_mode = INPUT_MODE_VEL_RAMP`.<br>
|
||||
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`.<br>
|
||||
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`.
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ In the `odrivetool`, type `<axis>.requested_state = AXIS_STATE_ENCODER_OFFSET_CA
|
||||
To verify everything went well, check the following variables:
|
||||
|
||||
* `<axis>.error` should be 0.
|
||||
* `<axis>.encoder.config.offset` - This should print a number, like -326 or 1364.
|
||||
* `<axis>.encoder.config.phase_offset` - This should print a number, like -326 or 1364.
|
||||
* `<axis>.encoder.config.direction` - This should print 1 or -1.
|
||||
|
||||
### Encoder with index signal
|
||||
|
||||
+8
-93
@@ -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)
|
||||
|
||||
<!-- /TOC -->
|
||||
|
||||
@@ -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]<br>
|
||||
Activate the setpoint filter: `axis.controller.config.input_mode = INPUT_MODE_POS_FILTER`.<br>
|
||||
You can now control the velocity with `axis.controller.input_pos = 1` [turns].
|
||||
|
||||
<br>
|
||||
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.<br>
|
||||
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.
|
||||
|
||||
<br>
|
||||
In the above image blue is position and orange is velocity.
|
||||
|
||||
#### Parameters
|
||||
```
|
||||
<odrv>.<axis>.trap_traj.config.vel_limit = <Float>
|
||||
<odrv>.<axis>.trap_traj.config.accel_limit = <Float>
|
||||
<odrv>.<axis>.trap_traj.config.decel_limit = <Float>
|
||||
<odrv>.<axis>.controller.config.inertia = <Float>
|
||||
```
|
||||
|
||||
`vel_limit` is the maximum planned trajectory speed. This sets your coasting speed.<br>
|
||||
`accel_limit` is the maximum acceleration in turns / sec^2<br>
|
||||
`decel_limit` is the maximum deceleration in turns / sec^2<br>
|
||||
`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.
|
||||
```
|
||||
<odrv>.<axis>.motor.config.current_lim = <Float>
|
||||
<odrv>.<axis>.controller.config.vel_limit = <Float>
|
||||
```
|
||||
|
||||
#### 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:
|
||||
```
|
||||
<odrv>.<axis>.controller.input_pos = <Float>
|
||||
```
|
||||
|
||||
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`
|
||||
```
|
||||
<odrv>.<axis>.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`.<br>
|
||||
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`.<br>
|
||||
Set the velocity ramp rate (acceleration): `axis.controller.config.vel_ramp_rate = 0.5` [turn/s^2]<br>
|
||||
Activate the ramped velocity mode: `axis.controller.config.input_mode = INPUT_MODE_VEL_RAMP`.<br>
|
||||
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`.<br>
|
||||
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.
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user