Skip to content

Commit

Permalink
Merge branch 'master' into devel
Browse files Browse the repository at this point in the history
  • Loading branch information
madcowswe committed Sep 19, 2018
2 parents fb5cae8 + f01031f commit 47052c8
Show file tree
Hide file tree
Showing 9 changed files with 167 additions and 31 deletions.
12 changes: 11 additions & 1 deletion docs/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@

We will use the `<odrv>` as a placeholder for any ODrive object. Every ODrive controller is an ODrive object. In `odrivetool` this is usually `odrv0`. Furthermore we use `<axis>` as a placeholder for any axis, which is an attribute of an ODrive object (for example `odrv0.axis0`). An axis represents where the motors are connected. (axis0 for M0 or axis1 for M1)

### Table of contents
<!-- TOC depthFrom:2 depthTo:2 -->

- [Per-Axis commands](#per-axis-commands)
- [System monitoring commands](#system-monitoring-commands)
- [General system commands](#general-system-commands)
- [Setting up sensorless](#setting-up-sensorless)

<!-- /TOC -->

## Per-Axis commands

For the most part, both axes on the ODrive can be controlled independently.
Expand Down Expand Up @@ -75,7 +85,7 @@ An upcoming feature will enable automatic tuning. Until then, here is a rough tu

### Encoder position and velocity
* View encoder position with `<axis>.encoder.pos_estimate` [counts]
* View rotational velocity with `<axis>.encoder.pll_vel` [counts/s]
* View rotational velocity with `<axis>.encoder.vel_estimate` [counts/s]

### Motor current and torque estimation
* View the commanded motor current with `<axis>.motor.current_control.Iq_setpoint` [A]
Expand Down
6 changes: 2 additions & 4 deletions docs/configuring-vscode.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,8 @@ Before doing the VSCode setup, make sure you've installed all of your [prerequis
1. Install extensions. This can be done directly from VSCode (Ctrl+Shift+X)
* Required extensions:
* C/C++
* Recommended Extensions:
* Cortex-Debug
* vscode-icons
* Code Outline
* Recommended Extensions:
* Include Autocomplete
* Path Autocomplete
* Auto Comment Blocks
Expand Down Expand Up @@ -51,4 +49,4 @@ Note: If developing on Windows, you should have `arm-none-eabi-gdb` and `openOCD

## Cleaning the Build
This sometimes needs to be done if you change branches.
* Open a terminal (View -> Integrated Terminal) and enter `make clean`
* Open a terminal (View -> Integrated Terminal) and enter `make clean`
27 changes: 24 additions & 3 deletions docs/control.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,27 @@ The motor controller is a cascaded style position, velocity and current control

![Cascaded pos vel I loops](https://static1.squarespace.com/static/58aff26de4fcb53b5efd2f02/t/5b66284a0e2e72aae8818d64/1533421649405/CascadedController.png?format=2500w)

* The position controller is a P loop with a single proportional gain.
* The velocity controller is a PI loop.
* The current controller is a PI loop.
### Position loop:
The position controller is a P loop with a single proportional gain.
```text
pos_error = pos_setpoint - pos_feedback
vel_cmd = pos_error * pos_gain + vel_feedforward
```

### Velocity loop:
The velocity controller is a PI loop.
```text
vel_error = vel_cmd - vel_feedback
current_integral += vel_error * vel_integrator_gain
current_cmd = vel_error * vel_gain + current_integral + current_feedforward
```

### Current loop:
The current controller is a PI loop.
```text
current_error = current_cmd - current_fb
voltage_integral += current_error * current_integrator_gain
voltage_cmd = current_error * current_gain + voltage_integral (+ voltage_feedforward when we have motor model)
```

For more detail refer to [controller.cpp](https://github.com/madcowswe/ODrive/blob/master/Firmware/MotorControl/controller.cpp#L86).
5 changes: 3 additions & 2 deletions docs/developer-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,9 @@ $ python --version # should be 3.7 or later

#### Linux (Ubuntu)
```bash
sudo apt-get install gcc-arm-none-eabi
sudo apt-get install gdb-arm-none-eabi
sudo add-apt-repository ppa:team-gcc-arm-embedded/ppa
sudo apt-get update
sudo apt-get install gcc-arm-embedded
sudo apt-get install openocd
sudo add-apt-repository ppa:jonathonf/tup && sudo apt-get update && sudo apt-get install tup
```
Expand Down
13 changes: 6 additions & 7 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ permalink: /
# Getting Started

### Table of contents

<!-- MarkdownTOC depth=2 autolink=true bracket=round -->
<!-- TOC depthFrom:2 depthTo:2 -->

- [Hardware Requirements](#hardware-requirements)
- [Wiring up the ODrive](#wiring-up-the-odrive)
Expand All @@ -18,7 +17,7 @@ permalink: /
- [Position control of M0](#position-control-of-m0)
- [What's next?](#whats-next)

<!-- /MarkdownTOC -->
<!-- /TOC -->

## Hardware Requirements

Expand Down Expand Up @@ -123,9 +122,9 @@ Try step 5 again
2. Install the ODrive tools by opening a terminal and typing `pip install odrive` <kbd>Enter</kbd>
3. __Linux__: set up USB permissions
```bash
echo 'SUBSYSTEM=="usb", ATTR{idVendor}=="1209", ATTR{idProduct}=="0d[0-9][0-9]", MODE="0666"' | sudo tee /etc/udev/rules.d/50-odrive.rules
echo 'SUBSYSTEM=="usb", ATTR{idVendor}=="1209", ATTR{idProduct}=="0d[0-9][0-9]", MODE="0666"' | sudo tee /etc/udev/rules.d/91-odrive.rules
sudo udevadm control --reload-rules
sudo udevadm trigger # until you reboot you may need to do this everytime you reset the ODrive
sudo udevadm trigger
```

## Start `odrivetool`
Expand Down Expand Up @@ -175,7 +174,7 @@ For instance, to set the current limit of M0 to 10A you would type: `odrv0.axis0

### 2. Set other hardware parameters:

* `odrv0.config.brake_resistance` [Ohm]: This is the resistance of the brake resistor. If you are not using it, you may set it to `0`.
* `odrv0.config.brake_resistance` [Ohm]: This is the resistance of the brake resistor. If you are not using it, you may set it to `0`. Note that there may be some extra resistance in your wiring and in the screw terminals, so if you are getting issues while braking you may want to increase this parameter by around 0.05 ohm.
* `odrv0.axis0.motor.config.pole_pairs`: This is the number of **magnet poles** in the rotor, **divided by two**. You can simply count the number of permanent magnets in the rotor, if you can see them. _Note: this is not the same as the number of coils in the stator._
* `odrv0.axis0.motor.config.motor_type`: This is the type of motor being used. Currently two types of motors are supported: High-current motors (`MOTOR_TYPE_HIGH_CURRENT`) and Gimbal motors (`MOTOR_TYPE_GIMBAL`).

Expand Down Expand Up @@ -229,7 +228,7 @@ Let's get motor 0 up and running. The procedure for motor 1 is exactly the same,
### Other control modes
The ODrive also supports velocity control and current (torque) control.
* **Velocity control**: Set `odrv0.axis0.controller.config.control_mode = CTRL_MODE_VELOCITY_CONTROL`. You can now control the velocity with `odrv0.axis0.controller.vel_setpoint = 5000`. Units are counts/s.
* **Current control**: Set `odrv0.axis0.controller.config.control_mode = CTRL_MODE_CURRENT_CONTROL`. You can now control the current with `odrv0.axis0.controller.vel_setpoint = 3`. Units are A. **NOTE**: There is no velocity limiting in current control mode. Make sure that you don't overrev the motor, or exceed the max speed for your encoder.
* **Current control**: Set `odrv0.axis0.controller.config.control_mode = CTRL_MODE_CURRENT_CONTROL`. You can now control the current with `odrv0.axis0.controller.current_setpoint = 3`. Units are A. **NOTE**: There is no velocity limiting in current control mode. Make sure that you don't overrev the motor, or exceed the max speed for your encoder.

## What's next?

Expand Down
11 changes: 4 additions & 7 deletions docs/interfaces.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,16 @@
The ODrive can be controlled over various ports and protocols. If you're comfortable with embedded systems development, you can also run custom code directly on the ODrive. For that refer to the [developer documentation](developer-guide.md).

### Table of contents

<!-- MarkdownTOC depth=2 autolink=true bracket=round -->
<!-- TOC depthFrom:2 depthTo:2 -->

- [Pinout](#pinout)
- [Native Protocol](#native-protocol)
- [ASCII Protocol](#ascii-protocol) (and Arduino)
- [ASCII protocol](#ascii-protocol)
- [Step/direction](#stepdirection)
- [RC PWM input](#rc-pwm-input) (coming soon)
- [RC PWM input](#rc-pwm-input)
- [Ports](#ports)
- [USB](#usb)
- [UART](#uart)

<!-- /MarkdownTOC -->
<!-- /TOC -->

## Pinout

Expand Down
14 changes: 13 additions & 1 deletion docs/odrivetool.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,18 @@

The ODrive Tool is the accompanying PC program for the ODrive. It's main purpose is to provide an interactive shell to control the device manually, as well as some supporting functions like firmware update.

### Table of contents
<!-- TOC depthFrom:2 depthTo:2 -->

- [Installation](#installation)
- [Multiple ODrives](#multiple-odrives)
- [Configuration Backup](#configuration-backup)
- [Device Firmware Update](#device-firmware-update)
- [Flashing with an STLink](#flashing-with-an-stlink)
- [Liveplotter](#liveplotter)

<!-- /TOC -->

## Installation

Refer to the [Getting Started guide](getting-started#downloading-and-installing-tools).
Expand Down Expand Up @@ -62,7 +74,7 @@ Note that this command will connect to GitHub servers to retrieve the latest fir
If you have a non-default configuration saved on the device, ODrive Tool will try to carry over the configuration across the firmware update. If any of the settings are removed or renamed, you will get warning messages.

<details><summary markdown="span">How to flash a custom firmware</summary><div markdown="block">
If you want to flash a specific firmware file instead of automatically downloading one, you can run `odrivetool dfu [path/to/firmware/file.hex]`.
If you want to flash a specific firmware file instead of automatically downloading one, you can run `odrivetool dfu path/to/firmware/file.hex`

You can download one of the officially released firmware files from [here](https://github.com/madcowswe/ODrive/releases). You will need one of the __.hex__ files (not the __.elf__ file). Make sure you select the file that matches your board version.

Expand Down
108 changes: 103 additions & 5 deletions docs/troubleshooting.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
# Troubleshooting

Table of Contents:
<!-- TOC depthFrom:2 depthTo:2 -->

- [Error codes](#error-codes)
- [Common Axis Errors](#common-axis-errors)
- [Common Motor Errors](#common-motor-errors)
- [Common Encoder Errors](#common-encoder-errors)
- [USB Connectivity Issues](#usb-connectivity-issues)
- [Firmware Issues](#firmware-issues)
- [Other issues that may not produce an error code](#other-issues-that-may-not-produce-an-error-code)

<!-- /TOC -->

## Error codes
If your ODrive is not working as expected, run `odrivetool` and type `hex(<axis>.error)` <kbd>Enter</kbd> where `<axis>` is the axis that isn't working. This will display a [hexadecimal](https://en.wikipedia.org/wiki/Hexadecimal) representation of the error code. Each bit represents one error flag.

Expand All @@ -21,18 +34,64 @@ The axis error may say that some other component has failed. Say it reports `ERR
* Encoder error flags defined [here](../Firmware/MotorControl/encoder.hpp).
* Sensorless estimator error flags defined [here](../Firmware/MotorControl/sensorless_estimator.hpp).

## DRV fault
## Common Axis Errors

* `ERROR_INVALID_STATE = 0x01`

Typically returned along with another error. Resolve that error and then reboot using `odrv0.reboot()` or remoivng power, waiting 5 seconds and restoring power to return to normal operating.

* `ERROR_DC_BUS_UNDER_VOLTAGE = 0x02`

Confirm that your power leads are connected securely. For initial testing a 12V PSU which can supply a couple of amps should be sufficient while the use of low current 'wall wart' plug packs may lead to inconsistent behaviour and is not recommended.

You can monitor your PUS voltage using liveplotter in odrive tool by entering `start_liveplotter(lambda: [odrv0.vbus_voltage])`. If you see your votlage drop below ~ 8V then you will trip this error. Even a relatively small motor can draw multiple kW momentary and so unless you have a very large PSU or are running of a battery you may encounter this error when executing high speed movements with a high current limit. To limit your PSU power draw you can limit your motor current and/or velocity limit `odrv0.axis0.controller.config.vel_limit` and `odrv0.axis0.motor.config.current_lim`.

* `ERROR_DC_BUS_OVER_VOLTAGE = 0x04`

Confirm that you have a break resistor of the correct value connected securly and that `odrv0.config.brake_resistance` is set to the value of your break resistor.

You can monitor your PUS voltage using liveplotter in odrive tool by entering `start_liveplotter(lambda: [odrv0.vbus_voltage])`. If during a move you see the voltage rise above your PSU's nominal set voltage then you have your break resistance set too low. This may happen if you are using long wires or small gauge wires to connect your break resistor to your odrive which will added extra resistance. This extra resistance needs to be accounted for to prevent this voltage spike. If you have checked all your connections you can also try increasing your break resistance by ~ 0.01 Ohm at a time to a maximum of 0.05 greater than your break resistor value.

## Common Motor Errors

* `ERROR_PHASE_RESISTANCE_OUT_OF_RANGE = 0x0001` and `ERROR_PHASE_INDUCTANCE_OUT_OF_RANGE = 0x0002`

During calibration the motor resistance and [inductance](https://en.wikipedia.org/wiki/Inductance) is measured. If the measured motor resistance or inductance falls outside a set range this error will be returned. Check that all motor leads are connected securely.

The measured values can be viewed using odrivetool as is shown below:
```
In [2]: odrv0.axis0.motor.config.phase_inductance
Out[2]: 1.408751450071577e-05
In [3]: odrv0.axis0.motor.config.phase_resistance
Out[3]: 0.029788672924041748
```
Some motors will have a considerably different phase resistance and inductance than this. For example, gimbal motors, some small motors (e.g. < 10A peak current). If you think this applies to you try increasing `odrv0.axis0.motor.config.resistance_calib_max_voltage` from its default value of 1 using odrive tool and repeat the motor calibration process. If your motor has a small peak current draw (e.g. < 20A) you can also try decreasing `odrv0.axis0.motor.config.calibration_current` from its default value of 10A.

* `ERROR_DRV_FAULT = 0x0008`

The ODrive v3.4 is known to have a hardware issue whereby the motors would stop operating
when applying high currents to M0. The reported error of both motors in this case
is `ERROR_DRV_FAULT`.

The conjecture is that the high switching current creates large ripples in the
power supply of the DRV8301 gate driver chips, thus tripping its undervoltage
fault detection.
power supply of the DRV8301 gate driver chips, thus tripping its under-voltage fault detection.

* Limit the M0 current to 40A. The lowest current at which the DRV fault was observed is 45A on one test motor and 50A on another test motor.
* Refer to [this post](https://discourse.odriverobotics.com/t/drv-fault-on-odrive-v3-4/558) for instructions for a hardware fix
To resolve this issue you can limit the M0 current to 40A. The lowest current at which the DRV fault was observed is 45A on one test motor and 50A on another test motor. Refer to [this post](https://discourse.odriverobotics.com/t/drv-fault-on-odrive-v3-4/558) for instructions for a hardware fix.

## Common Encoder Errors

* `ERROR_CPR_OUT_OF_RANGE = 0x02`

Confirm you have entered the correct count per rotation (CPR) for [your encoder](https://docs.odriverobotics.com/encoders). Note that the AMT encoders are configurable using the micro-switches on the encoder PCB and so you may need to check that these are in the right positions. If your encoder lists its pulse per rotation (PPR) multiply that number by four to get CPR.

* `ERROR_NO_RESPONSE = 0x04`

Confirm that your encoder is plugged into the right pins on the odrive board.

* `ERROR_INDEX_NOT_FOUND_YET = 0x20`

Check that your encoder is a model that has an index pulse. If your encoder does not have a wire connected to pin Z on your odrive then it does not output an index pulse.


## USB Connectivity Issues
Expand All @@ -47,3 +106,42 @@ fault detection.
* Run `odrivetools` with the `--verbose` option.
* Run `PYUSB_DEBUG=debug odrivetools` to get even more log output.
* If you're a developer you can use Wireshark to capture USB traffic.
* Try a different USB cable
* Try routing your USB cable so that it is far away from the motor and PSU cables to reduce EMI

## Firmware Issues

### Failure to build the firmware when running `make`
- Clear out temporary files from previous compiles by first running `make clean` to prevent conflicts.
- **Windows users**: Confirm that tup has been correctly added to path by running `env|grep PATH` in Git Bash. If you see no mention of tup then you must [add its location to your PATH environment variable.](https://docs.alfresco.com/4.2/tasks/fot-addpath.html). Note that you may need to restart for the added path to take effect.

### Failure to flash the firmware when running `make flash`
- If using an ST-link, confirm that the ST-link is connected the correct pins and that you have power supplied to the board. This can be by the 5V pin on the ST link or the main DC power jack. No power is supplied over the USB connection.

## Other issues that may not produce an error code

### Motor cuts off or spins uncontrollably at high rotational speeds (ie: > 5000 RPM)
- You may be approaching the limit of your encoder. The 2400 count/rotation encoders that were initially included with odrive are realistically limited to around 5000 RPM. Exceeding this speed causes the odrive to lose track of position. This can only be fixed by using an alternative encoder or gearing down the output of your motor onto your encoder so that it still sees < 5000RPM at full speed. If using the gearing options be sure to change your counts/rotation accordingly.

### Motor vibrates when stationary or makes constant noise

- Likely due to incorrect gains, specifically `vel_gain` may be set too high. Try following the [tuning procedure](https://docs.odriverobotics.com/commands).
- Check encoder shaft connection. Grub screws may vibrate lose with time. If using a CUI shaft encoder try remounting the plastic retaining ring and confirm that it is not coming into contact with the encoder housing. Also confirm that the encoder is securely mounted.
- If you are using a high resolution encoder (>4000 counts/rotation) then increasing encoder_pll_bandwidth may help reduce vibration.
- If you connect your motor to an object with a large moment of inertia (such as a flywheel) this will help reduce vibrations at high gians. However, make sure that all connections are ridged. Cheap shaft couplers or belts under low tension can introduce enough flex into a system that the motor may still vibrate independently.

### Motor overshoots target position or oscillates back and forth
- Likely due to incorrect gains for a given motor current limit. Specifically `pos_gain` is set too high. Try following the [tuning procedure](https://docs.odriverobotics.com/commands).
- Increase the current limit of your motor for more torque.

### Motor slowly starts to increase in speed
- Encoder has likely slipped. This may occur when your motor makes a hard stop or violently vibrates causing something to come lose. Power the board off and on again so that it undertakes a new calibration. If you are using an index search on startup then you will need to repeat the index calibration process.

### Motor feels like it has less torque than it should and/or gets hot sitting still while under no load.
- Encoder has likely slipped causing the motor controller to commutate the wrong windings slightly which reduces output torque and produces excess heat as the motor 'fights itself'.

### False steps or direction changes when using step/dir
- Prior to Odrive board V3.5 no filtering is present on the GPIO pins used for step/dir interface and so inductively coupled noise may causes false steps to be detected. Odrive V3.5 and has onboard filtering to resolve this issue.
- If you experience this issue use a twisted pair cable between your microcontroller that’s generating the step/dir signals and your odrive board. A section cut from cat-5 cable works well as does just twisting some normal insulated wire together.
- Ensure that the step/dir signal cables are not draped over the odrive board, are not running in parallel to the motor or power supply cables.
- If the above does not resolve your issue on V3.4 boards and lower try adding a ~22 Ohm resistor in series with the step and direction pins along with a ~ 4.7 nF capacitor between the ground pin and the step and dir pins such as shown [here](https://cdn.discordapp.com/attachments/369667319280173069/420811057431445504/IMG_20180306_211224.jpg).
Loading

0 comments on commit 47052c8

Please sign in to comment.