Skip to content

Commit

Permalink
Merge branch 'master' into devel
Browse files Browse the repository at this point in the history
  • Loading branch information
Wetmelon committed Sep 30, 2020
2 parents 0f74eb9 + 400b442 commit e1ff203
Show file tree
Hide file tree
Showing 14 changed files with 54 additions and 28 deletions.
15 changes: 11 additions & 4 deletions .github/workflows/documentation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Build and publish HTML documentation website

on:
push:
branches: [ feature/doc_autogen ]
branches: [ master ]

jobs:
jekyll:
Expand Down Expand Up @@ -52,15 +52,22 @@ jobs:
cd /srv/jekyll/docs && \
bundle config path vendor/bundle && \
bundle install && \
JEKYLL_ENV=production bundle exec jekyll build
bundle exec jekyll build --baseurl \"\"
cd ..
mv docs/_site _site
rm -rdf docs
mv _site docs
touch docs/.nojekyll
"
touch .nojekyll
# Extra checks to reduce likelihood of defect build
test -f docs/CNAME
test -f docs/index.html
- name: Push to documentation branch
run: |
git config user.name "${GITHUB_ACTOR}"
git config user.email "${GITHUB_ACTOR}@users.noreply.github.com"
git add -f docs/_site
git add -f docs
git commit -m "jekyll build from Action ${GITHUB_SHA}"
git push --force origin HEAD:${REMOTE_BRANCH}
env:
Expand Down
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@ Please add a note of your changes below this heading if you make a Pull Request.
* Fixed bug of high current during lockin-ramp caused by `motor::update()` expecting a torque command instead of current
* Fixed bug where commanded velocity was extremely high just after sensorless ramp when using `input_mode` INPUT_MODE_VEL_RAMP caused by `vel_setpoint` and `axis.config.sensorless_ramp.vel` being in different units

### Fixed
* Fixed bug of high current during lockin-ramp caused by `motor::update()` expecting a torque command instead of current
* Fixed bug where commanded velocity was extremely high just after sensorless ramp when using `input_mode` INPUT_MODE_VEL_RAMP caused by `vel_setpoint` and `axis.config.sensorless_ramp.vel` being in different units

# Releases
## [0.5.0] - 2020-08-03
### Added
* AC Induction Motor support.
Expand Down
2 changes: 1 addition & 1 deletion Firmware/MotorControl/low_level.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ void vbus_sense_adc_cb(ADC_HandleTypeDef* hadc, bool injected) {
}

// This is the callback from the ADC that we expect after the PWM has triggered an ADC conversion.
// TODO: Document how the phasing is done, link to timing diagram
// Timing diagram: Firmware/timing_diagram_v3.png
void pwm_trig_adc_cb(ADC_HandleTypeDef* hadc, bool injected) {
#define calib_tau 0.2f //@TOTO make more easily configurable
constexpr float calib_filter_k = CURRENT_MEAS_PERIOD / calib_tau;
Expand Down
3 changes: 2 additions & 1 deletion Firmware/fibre/tools/interface_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ def regularize_valuetype(path, name, elem):
elem['flags'][k]['value'] = 0 if current_bit is None else (1 << current_bit)
bit = bit if current_bit is None else current_bit + 1
if 'nullflag' in elem:
elem['flags'] = OrderedDict([(elem['nullflag'], {'value': 0, 'bit': None}), *elem['flags'].items()])
elem['flags'] = OrderedDict([(elem['nullflag'], OrderedDict({'name': elem['nullflag'], 'value': 0, 'bit': None})), *elem['flags'].items()])
elem['values'] = elem['flags']
elem['is_flags'] = True
elem['is_enum'] = True
Expand Down Expand Up @@ -653,6 +653,7 @@ def token_transform(token):
env.filters['to_c_string'] = lambda x: '\n'.join(('"' + line.replace('"', '\\"') + '"') for line in json.dumps(x, separators=(',', ':')).replace('{"name"', '\n{"name"').split('\n'))
env.filters['tokenize'] = tokenize
env.filters['diagonalize'] = lambda lst: [lst[:i + 1] for i in range(len(lst))]
env.filters['debug'] = lambda x: print(x)

template = env.from_string(template_file.read())

Expand Down
Binary file added Firmware/timing_diagram_v3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 3 additions & 2 deletions docs/_layouts/default.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
<![endif]-->
</head>
<body>
<div style="position: absolute;top: 0;left: 0;width: 100%;background-color: #5bc0de;height: 20px;text-align: center;font-weight: 600">The docs reflect firmware version 0.5.1. There are many breaking <a href="https://github.com/madcowswe/ODrive/blob/master/CHANGELOG.md">changes</a>. Please find docs for v0.4.12 <a href="https://github.com/madcowswe/ODrive/blob/fw-v0.4.12/docs/getting-started.md">here</a>.</div>
<div class="wrapper">
<header>
<div>
Expand Down Expand Up @@ -78,7 +79,7 @@ <h1><a href="{{ "/" | absolute_url }}">{{ site.title | default: site.github.repo
<path fill-rule="evenodd" d="M0 12v3h3l8-8-3-3-8 8zm3 2H1v-2h1v1h1v1zm10.3-9.3L12 6 9 3l1.3-1.3a.996.996 0 0 1 1.41 0l1.59 1.59c.39.39.39 1.02 0 1.41z"></path>
</svg>
{% if page.edit_url %}
{% assign edit_url = "https://www.github.com/madcowswe/ODrive/edit/master/" | append: edit_url %}
{% assign edit_url = "https://www.github.com/madcowswe/ODrive/edit/master/" | append: page.edit_url %}
{% else %}
{% assign edit_url = "https://www.github.com/madcowswe/ODrive/edit/master/docs/" | append: pagename | append: ".md" %}
{% endif %}
Expand All @@ -90,7 +91,7 @@ <h1><a href="{{ "/" | absolute_url }}">{{ site.title | default: site.github.repo
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="10" height="10" style="fill: #656565;">
<path d="M216 0h80c13.3 0 24 10.7 24 24v168h87.7c17.8 0 26.7 21.5 14.1 34.1L269.7 378.3c-7.5 7.5-19.8 7.5-27.3 0L90.1 226.1c-12.6-12.6-3.7-34.1 14.1-34.1H192V24c0-13.3 10.7-24 24-24zm296 376v112c0 13.3-10.7 24-24 24H24c-13.3 0-24-10.7-24-24V376c0-13.3 10.7-24 24-24h146.7l49 49c20.1 20.1 52.5 20.1 72.6 0l49-49H488c13.3 0 24 10.7 24 24zm-124 88c0-11-9-20-20-20s-20 9-20 20 9 20 20 20 20-9 20-20zm64 0c0-11-9-20-20-20s-20 9-20 20 9 20 20 20 20-9 20-20z"/>
</svg>
<a href="https://www.github.com/madcowswe/ODrive/edit/master/{{page.download.url}}">{{page.download.text}}</a>
<a href="https://www.github.com/madcowswe/ODrive/blob/master/{{page.download.url}}">{{page.download.text}}</a>
</div>
{% endif %}
</div>
Expand Down
2 changes: 1 addition & 1 deletion docs/can-protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ Configuration of the CAN parameters should be done via USB before putting the de

To set the desired baud rate, use `<odrv>.can.set_baud_rate(<value>)`. The baud rate can be done without rebooting the device. If you'd like to keep the baud rate, simply call `<odrv>.save_configuration()` before rebooting.

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).
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

Expand Down
1 change: 1 addition & 0 deletions docs/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ Possible values are listed [here](api/odrive.axis.controller.controlmode).

As of version v0.5.0, ODrive now intercepts the incoming commands and can apply filters to them. The old protocol values `pos_setpoint`, `vel_setpoint`, and `current_setpoint` are still used internally by the closed-loop cascade control, but the user cannot write to them directly. This allows us to condense the number of ways the ODrive accepts motion commands. The new commands are:

### Control Commands
* `<axis>.controller.input_pos = <turn>`
* `<axis>.controller.input_vel = <turn/s>`
* `<axis>.controller.input_torque = <torque in Nm>`
Expand Down
2 changes: 2 additions & 0 deletions docs/control.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ voltage_integral += current_error * current_integrator_gain
voltage_cmd = current_error * current_gain + voltage_integral (+ voltage_feedforward when we have motor model)
```

Note: `current_gain` and `current_integrator_gain` are automatically set according to `motor.config.current_control_bandwidth`

For more detail refer to [controller.cpp](https://github.com/madcowswe/ODrive/blob/master/Firmware/MotorControl/controller.cpp#L86).

### Controller Details:
Expand Down
13 changes: 8 additions & 5 deletions docs/encoders.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ That's it, now on every reboot the motor will turn in one direction until it fin
* If your motor has problems reaching the index location due to the mechanical load, you can increase `<axis>.motor.config.calibration_current`.

### Reversing index search
Sometimes you would like the index search to only happen in a particular direction (the reverse of the default), instead of swapping the motor leads, you can ensure the following three values are negative:
Sometimes you would like the index search to only happen in a particular direction (the reverse of the default). Instead of swapping the motor leads, you can ensure that the following three values are negative:
* `<axis0>.config.calibration_lockin.vel`
* `<axis0>.config.calibration_lockin.accel`
* `<axis0>.config.calibration_lockin.ramp_distance`
Expand Down Expand Up @@ -78,7 +78,7 @@ Do you still have no errors? Awesome. Now, setup the motor and encoder to use kn
* `<axis>.encoder.config.pre_calibrated = True`
* `<axis>.motor.config.pre_calibrated = True `

And see if ODrive agrees that calibration worked by just running
And see if ODrive agrees that the calibration worked by just running
* `<axis>.encoder.config.pre_calibrated`

(using no "= True" ). Make sure that 'pre_calibrated' is in fact True.
Expand Down Expand Up @@ -121,20 +121,21 @@ Connect to the I pin, see if you get a pulse on a complete rotation. Sometimes t

If you are using SPI, use a logic analyzer and connect to the CLK, MISO, and CS pins. Set a trigger for the CS pin and ensure that the encoder position is being sent and is increasing/decreasing as you spin the motor. There is extremely cheap hardware that is supported by [Sigrok](https://sigrok.org/) for protocol analysis.


## Encoder Noise
Noise is found in all circuits, life is just about figuring out if it is preventing your system from working. Lots of users have no problems with noise interfering with their ODrive operation, others will tell you "_I've been using the same encoder as you with no problems_". Power to 'em, that may be true, but it doesn't mean it will work for you. If you are concerned about noise, there are several possible sources:

* Importantly, encoder wires may be too close to motor wires, avoid overlap as much as possible
* Long wires between encoder and ODrive
* Use of ribbon cable

The following _might_ mitigate noise problems. Use shielded cable, or use twisted pairs, where one side of each twisted pair is tied to ground, the other side is tied to your signal. If you are using SPI, use a 20-50 ohm resistor in series on CLK, which is more susceptible noise.
The following _might_ mitigate noise problems. Use shielded cable, or use twisted pairs, where one side of each twisted pair is tied to ground and the other side is tied to your signal. If you are using SPI, use a 20-50 ohm resistor in series on CLK, which is more susceptible noise.

If you are using an encoder with an index signal, another problem that has been encountered is with noise on the Z input of ODrive. Symptoms for this problem include:
If you are using an encoder with an index signal, another problem that has been encountered is noise on the Z input of ODrive. Symptoms for this problem include:
* difficulty with requested_state = AXIS_STATE_FULL_CALIBRATION_SEQUENCE, where your calibration sequence may not complete
* strange behavior after performing odrv0.save_configuration() and odrv0.reboot()
* when performing an index_search, the motor does not return to the same position each time.
One easy step that _might_ fix the noise on the Z input has been to solder a 22nF-47nF capacitor to the Z pin and the GND pin on the underside of the ODrive board.
One easy step that _might_ fix the noise on the Z input is to solder a 22nF-47nF capacitor to the Z pin and the GND pin on the underside of the ODrive board.

## Hall feedback pinout
If position accuracy is not a concern, you can use A/B/C hall effect encoders for position feedback.
Expand Down Expand Up @@ -178,6 +179,8 @@ Some of these chips come with evaluation boards that can simplify mounting the c
- The encoder's MOSI should be tied to 3.3V (AMS encoders only. CUI encoders don't have this pin.)
- The encoder's Chip Select (aka nCS/CSn) can be connected to any of the ODrive's GPIOs (caution: GPIOs 1 and 2 are usually used by UART).

If you are having calibration problems, make sure that your magnet is centered on the axis of rotation on the motor. Some users report that this has a significant impact on calibration. Also make sure that your magnet height is within range of the spec sheet.

2. In `odrivetool`, run:

<axis>.encoder.config.abs_spi_cs_gpio_pin = 4 # or which ever GPIO pin you choose
Expand Down
21 changes: 13 additions & 8 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ permalink: /
- [Other control modes](#other-control-modes)
- [Watchdog Timer](#watchdog-timer)
- [What's next?](#whats-next)
- [Upgrading from 0.4.12](#upgrading-from-0412)

<!-- /TOC -->

Expand All @@ -41,7 +42,7 @@ permalink: /

</div></details>

* A power supply (12V-24V for the 24V board variant, 12V-48V for the 48V board variant). A battery is also fine. Some advice on choosing a power supply can be found [here](https://things-in-motion.blogspot.com/2018/12/how-to-select-right-power-source-for.html).
* A power supply (12V-24V for the 24V board variant, 12V-56V for the 56V board variant). A battery is also fine. Some advice on choosing a power supply can be found [here](https://things-in-motion.blogspot.com/2018/12/how-to-select-right-power-source-for.html).
<details><summary markdown="span">What voltage variant do I have?</summary><div markdown="block">
On all ODrives shipped July 2018 or after have a silkscreen label clearly indicating the voltage variant.

Expand All @@ -61,13 +62,13 @@ All non-power I/O is 3.3V output and 5V tolerant on input, on ODrive v3.3 and ne
### Wiring up the encoders
Connect the encoder(s) to J4. The A,B phases are required, and the Z (index pulse) is optional. The A,B and Z lines have 3.3k pull up resistors, for use with open-drain encoder outputs. For single ended push-pull signals with weak drive current (\<4mA), you may want to desolder the pull-ups.

![Image of ODrive all hooked up](https://docs.google.com/drawings/d/e/2PACX-1vTCD0P40Cd-wvD7Fl8UYEaxp3_UL81oI4qUVqrrCJPi6tkJeSs2rsffIXQRpdu6rNZs6-2mRKKYtILG/pub?w=1716&h=1281)
![Image of ODrive all hooked up](https://docs.google.com/drawings/d/e/2PACX-1vTpJziAisrkvV1kTL4vckAJkmJ-BAvTwN1GeZZNCNwpTHv47Cf8bpz-gJqK2Z3un6FCHT4E-rcuUg6c/pub?w=1716&h=1281)

### Safety & Power UP
<div class="alert">
Always think safety before powering up the ODrive if motors are attached. Consider what might happen if the motor spins as soon as power is applied.
</div>
* Unlike some devices, the ODrive does not recieve power over the USB port so the 24/48 volt power input is required even just to communicate with it using USB. It is ok to power up the ODrive before or after connecting the USB cable.
* Unlike some devices, the ODrive does not recieve power over the USB port so the 24/56 volt power input is required even just to communicate with it using USB. It is ok to power up the ODrive before or after connecting the USB cable.
* To power up the ODrive, connect the power source to the DC terminals. Make sure to pay attention to the polarity. A small spark is normal. This is caused by the capacitors charging up.

## Downloading and Installing Tools
Expand All @@ -81,7 +82,7 @@ Most instructions in this guide refer to a utility called `odrivetool`, so you s
2. Launch the command prompt.
* __Anaconda__: In the start menu, type `Anaconda Prompt` <kbd>Enter</kbd>
* __Standalone Python__: In the start menu, type `cmd` <kbd>Enter</kbd>
3. Install the ODrive tools by typing `pip install odrive` <kbd>Enter</kbd>
3. Install the ODrive tools by typing `pip install --upgrade odrive` <kbd>Enter</kbd>
4. Plug in a USB cable into the microUSB connector on ODrive, and connect it to your PC.
5. Use the [Zadig](http://zadig.akeo.ie/) utility to set ODrive driver to libusb-win32.
* Check 'List All Devices' from the options menu, and select 'ODrive 3.x Native Interface (Interface 2)'. With that selected in the device list choose 'libusb-win32' from the target driver list and then press the large 'install driver' button.
Expand All @@ -107,13 +108,13 @@ brew install libusb
```
5. Now that you have Python 3 and all the package managers, run:
```bash
pip3 install odrive
pip3 install --upgrade odrive
```

__Troubleshooting__
1. Permission Errors: Just run the previous command in sudo
```bash
sudo pip3 install odrive
sudo pip3 install --upgrade odrive
```

2. Dependency Errors: If the installer doesn't complete and you get a dependency
Expand All @@ -126,7 +127,7 @@ Try step 5 again

### Linux
1. [Install Python 3](https://www.python.org/downloads/). (for example, on Ubuntu, `sudo apt install python3 python3-pip`)
2. Install the ODrive tools by opening a terminal and typing `sudo pip3 install odrive` <kbd>Enter</kbd>
2. Install the ODrive tools by opening a terminal and typing `sudo pip3 install --upgrade odrive` <kbd>Enter</kbd>
* This should automatically add the udev rules. If this fails for some reason you can add them manually:
```bash
echo 'SUBSYSTEM=="usb", ATTR{idVendor}=="1209", ATTR{idProduct}=="0d[0-9][0-9]", MODE="0666"' | sudo tee /etc/udev/rules.d/91-odrive.rules
Expand Down Expand Up @@ -230,7 +231,7 @@ You can save all `.config` parameters to persistent memory so the ODrive remembe
## Position control of M0
Let's get motor 0 up and running. The procedure for motor 1 is exactly the same, so feel free to substitute `axis0` wherever it says `axis0`.
Let's get motor 0 up and running. The procedure for motor 1 is exactly the same, so feel free to substitute `axis1` wherever it says `axis0`.

1. Type `odrv0.axis0.requested_state = AXIS_STATE_FULL_CALIBRATION_SEQUENCE` <kbd>Enter</kbd>. After about 2 seconds should hear a beep. Then the motor will turn slowly in one direction for a few seconds, then back in the other direction.

Expand Down Expand Up @@ -373,3 +374,7 @@ You can now:
* See how you can improve the behavior during the startup procedure, like [bypassing encoder calibration](encoders.md#encoder-with-index-signal).
If you have any issues or any questions please get in touch. The [ODrive Community](https://discourse.odriverobotics.com/) warmly welcomes you.
## Upgrading from 0.4.12
A new version (0.5.1) of ODrive firmware has released, complete with a new odrivetool. Follow the installation instructions, making sure to add the `--upgrade` flag to pip commands, and check out the [Changelog](../CHANGELOG.md) for changes!
2 changes: 1 addition & 1 deletion docs/hoverboard.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ Check the status of the encoder object:
odrv0.axis0.encoder
```

Check that there are no errors. If your hall sensors has a standard timing angle then `offset_float` should be close to 0.5.
Check that there are no errors. If your hall sensors has a standard timing angle then `offset_float` should be close to 0.5 or 1.5.
```txt
error = 0x0000 (int)
offset_float = 0.5126956701278687 (float)
Expand Down
3 changes: 2 additions & 1 deletion docs/odrivetool.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,12 @@ To compile firmware from source, refer to the [developer guide](developer-guide)
### Troubleshooting

* __Windows__: During the update, a new device called "STM32 BOOTLOADER" will appear. Open the [Zadig utility](http://zadig.akeo.ie/) and set the driver for "STM32 BOOTLOADER" to libusb-win32. After that the firmware update will continue.
* __Linux__: Try running `sudo odrivetool dfu` instead of `odrivetool dfu`.
* On some machines you will need to unplug and plug back in the USB cable to make the PC understand that we switched from regular mode to bootloader mode.
* If the DFU script can't find the device, try forcing it into DFU mode.

<details><summary markdown="span">How to force DFU mode (ODrive v3.5 and newer)</summary><div markdown="block">
Flick the DIP switch that "DFU, RUN" to "DFU" and power cycle the board. After you're done upgrading firmware, don't forget to put the switch back into the "RUN" position and power cycle the board again.
Flick the DIP switch that says "DFU, RUN" to "DFU" and power cycle the board. If that alone doesn't work, also connect the pin "GPIO6" to "GND". After you're done upgrading firmware, don't forget to put the switch back into the "RUN" position and power cycle the board again.
</div></details>

<details><summary markdown="span">How to force DFU mode (ODrive v3.1, v3.2)</summary><div markdown="block">
Expand Down
Loading

0 comments on commit e1ff203

Please sign in to comment.