From a8a797fd45a8151ffb13faf84b5ee0f48e55acc0 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Fri, 22 Jun 2018 14:43:52 -0700 Subject: [PATCH 01/14] Update getting-started.md --- docs/getting-started.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/docs/getting-started.md b/docs/getting-started.md index 2036796b..b0953831 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -82,20 +82,25 @@ Most instructions in this guide refer to a utility called `odrivetool`, so you s ### OSX +We are going to run the following commands for installation in Terminal. 1. If you don't already have it, install homebrew: -```sh +```bash /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" ``` 2. Install python: -```sh +```bash brew install python ``` 3. If you get the error: `Error: python 2.7.14_2 is already installed`, then upgrade to Python 3 by running: -```sh +```bash brew upgrade python ``` -4. Now that you have Python 3 and all the package managers, run: -```sh +4. The odrive tools uses libusb to communicate to the ODrive: +```bash +brew install libusb +``` +5. Now that you have Python 3 and all the package managers, run: +```bash pip3 install odrive ``` From e875348740c231301f7e5b57bdefe21cbdb34d38 Mon Sep 17 00:00:00 2001 From: Deezmaker Labs Date: Fri, 22 Jun 2018 20:00:57 -0700 Subject: [PATCH 02/14] Added 4x multiplier note to MAX CPR in hopes to make it clear for firmware settings --- docs/encoders.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/encoders.md b/docs/encoders.md index 9c3c52ba..47ec0944 100644 --- a/docs/encoders.md +++ b/docs/encoders.md @@ -5,11 +5,11 @@ Contributions to this table highly encouraged! Encoder|Manufacturer|Output|Index|Max CPR|Max RPM|Voltage|Supported|Price|Link|Datasheet :--|:--|:--|:-:|:-:|:-:|:-:|:--|:--|:--|:-- -AMT102|CUI|Quadrature|Yes|8192|-|5V|Yes|-|-|- -AMT203|CUI|Quadrature + Absolute|Yes|4096|-|5V|Quadrature Only|-|-|- -AS5047P|AMS|Quadrature + Absolute|Yes|4096|28k|3.3V or 5V|Quadrature Only|-|-|- -E6B2-CWZ6C|Omron|Quadrature|Yes|8000|-|5-24V|Yes|-|-|[Datasheet](http://www.ia.omron.com/products/family/487/) -J733|-|Quadrature|No|2400|-|5-24V|Yes|-|-|- +AMT102|CUI|Quadrature|Yes|8192 (2048 * 4)|-|5V|Yes|-|-|- +AMT203|CUI|Quadrature + Absolute|Yes|4096 (1024 * 4)|-|5V|Quadrature Only|-|-|- +AS5047P|AMS|Quadrature + Absolute|Yes|4096 (1024 * 4)|28k|3.3V or 5V|Quadrature Only|-|-|- +E6B2-CWZ6C|Omron|Quadrature|Yes|8000 (2000 * 4)|-|5-24V|Yes|-|-|[Datasheet](http://www.ia.omron.com/products/family/487/) +J733|-|Quadrature|No|2400 (600 * 4)|-|5-24V|Yes|-|-|- ## Encoder Calibration From 7f4ec76fe7cc51a462b5167e29ab9ed7857b676c Mon Sep 17 00:00:00 2001 From: Deezmaker Labs Date: Fri, 22 Jun 2018 20:23:31 -0700 Subject: [PATCH 03/14] Corrected `odrv0.axis0.controller.config.vel_limit` --- docs/getting-started.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started.md b/docs/getting-started.md index b0953831..d671276e 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -157,7 +157,7 @@ You can read more about the odrivetool [here](odrivetool.md). The largest effect on modulation magnitude is speed. There are other smaller factors, but in general: if the motor is still it's not unreasonable to have 50A in the motor from 5A on the power supply. When the motor is spinning close to top speed, the power supply current and the motor current will be somewhat close to each other. - * The velocity limit: `odrv0.axis0.motor.config.vel_limit` [counts/s]. The motor will be limited to this speed; again the default value is quite slow. + * The velocity limit: `odrv0.axis0.controller.config.vel_limit` [counts/s]. The motor will be limited to this speed; again the default value is quite slow. * You can change `odrv0.axis0.motor.config.calibration_current` [A] to the largest value you feel comfortable leaving running through the motor continously when the motor is stationary. 2. Set other hardware parameters: From 5e9df151d80879689b60b9eb279917c8a64734b2 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Sat, 23 Jun 2018 17:35:08 -0700 Subject: [PATCH 04/14] add yes_no_prompt to imports --- tools/odrive/configuration.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/odrive/configuration.py b/tools/odrive/configuration.py index eab40653..ff220a8d 100644 --- a/tools/odrive/configuration.py +++ b/tools/odrive/configuration.py @@ -3,7 +3,7 @@ import json import os import tempfile import fibre.remote_object -from odrive.utils import OperationAbortedException +from odrive.utils import OperationAbortedException, yes_no_prompt def get_dict(obj, is_config_object): result = {} @@ -51,7 +51,7 @@ def backup_config(device, filename, logger): logger.info("Saving configuration to {}...".format(filename)) if os.path.exists(filename): - if not odrive.utils.yes_no_prompt("The file {} already exists. Do you want to override it?".format(filename), True): + if not yes_no_prompt("The file {} already exists. Do you want to override it?".format(filename), True): raise OperationAbortedException() data = get_dict(device, False) From 9108f8625118f76e7d1beac6bd752b842cf67fb6 Mon Sep 17 00:00:00 2001 From: mvelado Date: Mon, 25 Jun 2018 21:29:41 -0400 Subject: [PATCH 05/14] Fixed odrive_demo.py to actually work --- tools/odrive_demo.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/odrive_demo.py b/tools/odrive_demo.py index af7a203a..0e418495 100755 --- a/tools/odrive_demo.py +++ b/tools/odrive_demo.py @@ -19,18 +19,18 @@ my_drive = odrive.find_any() print("Bus voltage is " + str(my_drive.vbus_voltage) + "V") # Or to change a value, just assign to the property -my_drive.motor0.pos_setpoint = 3.14 -print("Position setpoint is " + str(my_drive.motor0.pos_setpoint)) +my_drive.axis0.controller.pos_setpoint = 3.14 +print("Position setpoint is " + str(my_drive.axis0.controller.pos_setpoint)) # And this is how function calls are done: -my_drive.motor0.set_pos_setpoint(0.0, 0.0, 0.0) +my_drive.axis0.controller.set_pos_setpoint(0.0, 0.0, 0.0) # A sine wave to test t0 = time.monotonic() while True: setpoint = 10000.0 * math.sin((time.monotonic() - t0)*2) print("goto " + str(int(setpoint))) - my_drive.motor0.set_pos_setpoint(setpoint, 0.0, 0.0) + my_drive.axis0.controller.set_pos_setpoint(setpoint, 0.0, 0.0) time.sleep(0.01) From 71088ffb9c3e67f8ec146f7e5e32c6a1c2774341 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Mon, 25 Jun 2018 18:53:13 -0700 Subject: [PATCH 06/14] fix pause focus stealing --- tools/odrive/utils.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tools/odrive/utils.py b/tools/odrive/utils.py index bc466f9c..0f5c58b8 100755 --- a/tools/odrive/utils.py +++ b/tools/odrive/utils.py @@ -69,10 +69,8 @@ def start_liveplotter(get_var_callback): while not cancellation_token.is_set(): plt.clf() plt.plot(vals) - if platform.system() == "Windows": - plt.pause(1/plot_rate) - else: - fig.canvas.flush_events() + fig.canvas.draw() + fig.canvas.start_event_loop(1/plot_rate) threading.Thread(target=fetch_data).start() threading.Thread(target=plot_data).start() From a8005a8ef78d8b8e3e0ce4735b6b5f87ab7914c9 Mon Sep 17 00:00:00 2001 From: mvelado Date: Mon, 25 Jun 2018 22:04:19 -0400 Subject: [PATCH 07/14] Added clarity changes in documentation --- docs/commands.md | 21 +++++++++++---------- docs/configurations.md | 0 docs/getting-started.md | 24 ++++++++++++++++++++---- 3 files changed, 31 insertions(+), 14 deletions(-) create mode 100644 docs/configurations.md diff --git a/docs/commands.md b/docs/commands.md index dc6b2b84..199795a4 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -1,6 +1,6 @@ # Parameters & Commands -We will use the `` as a placeholder for any ODrive object. In `odrivetool` this is usually `odrv0`. Furthermore we use `` as a placeholder for any axis (for example `odrv0.axis0`). +We will use the `` as a placeholder for any ODrive object. Every ODrive controller is an ODrive object. In `odrivetool` this is usually `odrv0`. Furthermore we use `` 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) ## Per-Axis commands @@ -11,26 +11,28 @@ For the most part, both axes on the ODrive can be controlled independently. The current state of an axis is indicated by `.current_state`. The user can request a new state by assigning a new value to `.requested_state`. The default state after startup is `AXIS_STATE_IDLE`. 1. `AXIS_STATE_IDLE` Disable motor PWM and do nothing. - 1. `AXIS_STATE_STARTUP_SEQUENCE` Run the [startup procedure](#startup-procedure). - 1. `AXIS_STATE_FULL_CALIBRATION_SEQUENCE` Run motor calibration and then encoder offset calibration (or encoder index search if `.encoder.use_index` is `True`). - 1. `AXIS_STATE_MOTOR_CALIBRATION` Measure phase resistance and phase inductance. + 2. `AXIS_STATE_STARTUP_SEQUENCE` Run the [startup procedure](#startup-procedure). + 3. `AXIS_STATE_FULL_CALIBRATION_SEQUENCE` Run motor calibration and then encoder offset calibration (or encoder index search if `.encoder.use_index` is `True`). + 4. `AXIS_STATE_MOTOR_CALIBRATION` Measure phase resistance and phase inductance of the motor. * To store the results set `.motor.config.pre_calibrated` to `True` and [save the configuration](#saving-the-configuration). After that you don't have to run the motor calibration on the next start up. * This modifies the variables `.motor.config.phase_resistance` and `.motor.config.phase_inductance`. - 1. `AXIS_STATE_SENSORLESS_CONTROL` Run sensorless control. + 5. `AXIS_STATE_SENSORLESS_CONTROL` Run sensorless control. * The motor must be calibrated (`.motor.is_calibrated`) * [`.controller.control_mode`](#control-mode) must be `True`. - 1. `AXIS_STATE_ENCODER_INDEX_SEARCH` Turn the motor in one direction until the encoder index is traversed. This state can only be entered if `.encoder.config.use_index` is `True`. - 1. `AXIS_STATE_ENCODER_OFFSET_CALIBRATION` Turn the motor in one direction for a few seconds and then back to measure the offset between the encoder position and the electrical phase. + 6. `AXIS_STATE_ENCODER_INDEX_SEARCH` Turn the motor in one direction until the encoder index is traversed. This state can only be entered if `.encoder.config.use_index` is `True`. + 7. `AXIS_STATE_ENCODER_OFFSET_CALIBRATION` Turn the motor in one direction for a few seconds and then back to measure the offset between the encoder position and the electrical phase. * Can only be entered if the motor is calibrated (`.motor.is_calibrated`). * A successful encoder calibration will make the `.encoder.is_ready` go to true. - 1. `AXIS_STATE_CLOSED_LOOP_CONTROL` Run closed loop control. + 8. `AXIS_STATE_CLOSED_LOOP_CONTROL` Run closed loop control. * The action depends on the [control mode](#control-mode). * Can only be entered if the motor is calibrated (`.motor.is_calibrated`) and the encoder is ready (`.encoder.is_ready`). ### Startup Procedure By default the ODrive takes no action at startup and goes to idle immediately. -This behavior can be changed by setting any of the following to `True`. The ODrive will sequence all enabled startup actions in the order shown below. +In order to change what startup procedures are used, set the startup procedures +you want to `True`. The ODrive will sequence all enabled startup actions selected +in the order shown below. * `.config.startup_motor_calibration` * `.config.startup_encoder_index_search` @@ -78,4 +80,3 @@ All variables that are part of a `[...].config` object can be saved to non-volat * `.serial_number`: A number that uniquely identifies your device. When printed in upper case hexadecimal (`hex(.serial_number).upper()`), this is identical to the serial number indicated by the USB descriptor. * `.fw_version_major`, `.fw_version_minor`, `.fw_version_revision`: The firmware version that is currently running. * `.hw_version_major`, `.hw_version_minor`, `.hw_version_revision`: The hardware version of your ODrive. - diff --git a/docs/configurations.md b/docs/configurations.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/getting-started.md b/docs/getting-started.md index d671276e..27426396 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -43,7 +43,7 @@ You will need: * A power supply (12V-24V for the 24V board variant, 12V-48V for the 48V board variant). A battery is also fine.
What voltage variant do I have?
On all ODrives shipped July 2018 or after have a silkscreen label clearly indicating the voltage variant. - + ODrives before this may or may not have this label. If you don't have a label, then you can look at the bus capacitors (8 gray cylinder components on the underside of the board). If they read 470uF, you have a 24V version; if they read 120uF you have a 48V version.
@@ -77,7 +77,7 @@ Most instructions in this guide refer to a utility called `odrivetool`, so you s 3. Install dependencies by typing `pip install pywin32==222` Enter 3. Install the ODrive tools by typing `pip install odrive` Enter 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. +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. @@ -104,6 +104,20 @@ brew install libusb pip3 install odrive ``` +__Troubleshooting__ +1. Permission Errors: Just run the previous command in sudo +```bash +sudo pip3 install odrive +``` + +2. Dependency Errors: If the installer doesn't complete and you get a dependency +error (Ex. "No module..." or "module_name not found") +```bash +sudo pip3 install module_name +``` +Try step 5 again + + ### Linux 1. [Install Python 3](https://www.python.org/downloads/). @@ -117,7 +131,9 @@ pip3 install odrive ## Start `odrivetool` -
__ODrive v3.4 and earlier:__ Your board does not come preflashed with any firmware. Follow the instructions [here](odrivetool#device-firmware-update) before you continue.
+
__ODrive v3.5 and later:__ Your board should come preflashed with firmware. If you run into problems, follow the instructions [here](odrivetool#device-firmware-update) on the DFU procedure before you continue.
+ +
__ODrive v3.4 and earlier:__ Your board does __not__ come preflashed with any firmware. Follow the instructions [here](odrivetool#device-firmware-update) on the STP Link procedure before you continue.
To launch the main interactive ODrive tool, type `odrivetool` Enter. Connect your ODrive and wait for the tool to find it. Now you can for instance type `odrv0.vbus_voltage` Enter to inpect the boards main supply voltage. It should look something like this: @@ -165,7 +181,7 @@ You can read more about the odrivetool [here](odrivetool.md). * `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.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`). - +
Which `motor_type` to choose?
If you're using a regular hobby brushless motor like [this](https://hobbyking.com/en_us/turnigy-aerodrive-sk3-5065-236kv-brushless-outrunner-motor.html) one, you should set `motor_mode` to `MOTOR_TYPE_HIGH_CURRENT`. For low-current gimbal motors like [this](https://hobbyking.com/en_us/turnigy-hd-5208-brushless-gimbal-motor-bldc.html) one, you should choose `MOTOR_TYPE_GIMBAL`. Do not use `MOTOR_TYPE_GIMBAL` on a motor that is not a gimbal motor, as it may overheat the motor or the ODrive. From 7acb0d20c777593d0b6265cfee79028820168e21 Mon Sep 17 00:00:00 2001 From: mvelado Date: Mon, 25 Jun 2018 22:38:21 -0400 Subject: [PATCH 08/14] Added clarity for different control modes --- docs/commands.md | 6 ++++++ docs/configurations.md | 0 docs/odrivetool.md | 8 ++++---- 3 files changed, 10 insertions(+), 4 deletions(-) delete mode 100644 docs/configurations.md diff --git a/docs/commands.md b/docs/commands.md index 199795a4..ef964ddd 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -51,6 +51,12 @@ Possible values are: * `CTRL_MODE_CURRENT_CONTROL` * `CTRL_MODE_VOLTAGE_CONTROL` - this one is not normally used. +## Control commands + +.controller.pos_setpoint = +.controller.current_setpoint = +.controller.vel_setpoint = + ### Tuning parameters The motion control gains are currently manually tuned: * `.controller.config.pos_gain = 20.0f` [(counts/s) / counts] diff --git a/docs/configurations.md b/docs/configurations.md deleted file mode 100644 index e69de29b..00000000 diff --git a/docs/odrivetool.md b/docs/odrivetool.md index efa1f14b..d3c4b67a 100644 --- a/docs/odrivetool.md +++ b/docs/odrivetool.md @@ -15,7 +15,7 @@ By default, `odrivetool` will connect to any ODrive it finds. If this is not wha To find the serial number of your ODrive, run `odrivetool`, connect exactly one ODrive and power it up. You should see this: ``` Connected to ODrive 306A396A3235 as odrv0 -In [1]: +In [1]: ``` `306A396A3235` is the serial number of this particular ODrive. If you want ODrive Tool to ignore all other devices you would close it and then run `odrivetool --serial-number 306A396A3235`. @@ -45,7 +45,7 @@ You can use ODrive Tool to back up and restore device configurations or transfer To update the ODrive to the newest firmware release, simply open up a terminal and run the following command: ``` -~ $ odrivetool dfu +~ $ odrivetool dfu ODrive control utility v0.3.7.dev Waiting for ODrive... Found ODrive 308039673235 (v3.5-24V) with firmware v0.3.7-dev @@ -118,12 +118,12 @@ Info : using stlink api v2 Info : Target voltage: 3.236027 Info : stm32f4x.cpu: hardware has 6 breakpoints, 4 watchpoints adapter speed: 2000 kHz -target halted due to debug-request, current mode: Thread +target halted due to debug-request, current mode: Thread xPSR: 0x01000000 pc: 0x08009224 msp: 0x20020000 auto erase enabled Info : device id = 0x10076413 Info : flash size = 1024kbytes -target halted due to breakpoint, current mode: Thread +target halted due to breakpoint, current mode: Thread xPSR: 0x61000000 pc: 0x20000046 msp: 0x20020000 Warn : no flash bank found for address 10000000 wrote 262144 bytes from file ODriveFirmware_v3.4-24V.elf in 10.194110s (25.113 KiB/s) From ecac6fe2b3c2b82dfb1dc5fbbf521022ff16bb23 Mon Sep 17 00:00:00 2001 From: mvelado Date: Mon, 25 Jun 2018 22:42:21 -0400 Subject: [PATCH 09/14] Fixed documentation commands --- docs/commands.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/commands.md b/docs/commands.md index ef964ddd..0b69139f 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -51,11 +51,11 @@ Possible values are: * `CTRL_MODE_CURRENT_CONTROL` * `CTRL_MODE_VOLTAGE_CONTROL` - this one is not normally used. -## Control commands +# Control Commands -.controller.pos_setpoint = -.controller.current_setpoint = -.controller.vel_setpoint = +* .controller.pos_setpoint = +* .controller.current_setpoint = +* .controller.vel_setpoint = ### Tuning parameters The motion control gains are currently manually tuned: From b46bb5180fb09d51d9829eb29bbc82bd5baf46d8 Mon Sep 17 00:00:00 2001 From: mvelado Date: Mon, 25 Jun 2018 22:44:32 -0400 Subject: [PATCH 10/14] Added control documentation for simple commands --- docs/commands.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/commands.md b/docs/commands.md index 0b69139f..e87dc4b1 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -53,9 +53,9 @@ Possible values are: # Control Commands -* .controller.pos_setpoint = -* .controller.current_setpoint = -* .controller.vel_setpoint = +* `.controller.pos_setpoint = ` +* `.controller.current_setpoint = ` +* `.controller.vel_setpoint = ` ### Tuning parameters The motion control gains are currently manually tuned: From 4b1900255a4b7a7412492deffbb39264e39f726b Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Mon, 25 Jun 2018 19:52:10 -0700 Subject: [PATCH 11/14] Update getting-started.md --- docs/getting-started.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/getting-started.md b/docs/getting-started.md index d671276e..aad88d73 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -190,7 +190,6 @@ Let's get motor 0 up and running. The procedure for motor 1 is exactly the same,
What's the point of this?
This procedure first measures your motor's electrical properties (namely phase resistance and phase inductance) and then the offset between the motor's electrical phase and the encoder position. -
The startup procedure is demonstrated [here](https://www.youtube.com/watch?v=VCX1bA2xnuY). @@ -198,15 +197,18 @@ Let's get motor 0 up and running. The procedure for motor 1 is exactly the same, **Note**: the rotor must be allowed to rotate without any biased load during startup. That means mass and weak friction loads are fine, but gravity or spring loads are not okay. Also note that in the video, the motors spin after initalisation, but in the current software the default behaviour is not like that.
My motor doesn't beep or doesn't turn
- Make sure the motor wires are connected firmly. Check the value of `odrv0.axis0.error` and then refer to the [error code documentation](troubleshooting.md#error-codes) for details. Once you have understood the error and fixed its cause, you may clear the error state (`odrv0.axis0.error = 0` Enter) and retry. You may also need to clear the error state of other subcomponents (e.g. `odrv0.axis0.motor.error`). -
- 2. Type `odrv0.axis0.requested_state = AXIS_STATE_CLOSED_LOOP_CONTROL` Enter. From now on the ODrive will try to hold the motor's position. If you try to turn it by hand, it will fight you gently. That is unless you bump up `odrv0.axis0.motor.config.current_lim`, in which case it will fight you more fiercely. +3. Send the motor a new position setpoint. `odrv0.axis0.controller.pos_setpoint = 10000` Enter. The units are in encoder counts. + +### 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. ## What's next? From be9627232c0647959c09bf10a3a816548b10f7ef Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Mon, 25 Jun 2018 20:44:57 -0700 Subject: [PATCH 12/14] make linebreaks line up on sentences. --- docs/commands.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/commands.md b/docs/commands.md index e87dc4b1..be67b09a 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -30,9 +30,8 @@ The current state of an axis is indicated by `.current_state`. The user ca ### Startup Procedure By default the ODrive takes no action at startup and goes to idle immediately. -In order to change what startup procedures are used, set the startup procedures -you want to `True`. The ODrive will sequence all enabled startup actions selected -in the order shown below. +In order to change what startup procedures are used, set the startup procedures you want to `True`. +The ODrive will sequence all enabled startup actions selected in the order shown below. * `.config.startup_motor_calibration` * `.config.startup_encoder_index_search` From 4cfd7eb0b513af43d6463d9c5b6b46b710ded145 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Mon, 25 Jun 2018 20:46:51 -0700 Subject: [PATCH 13/14] Update developer-guide.md --- 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 52c85171..e0c45d42 100644 --- a/docs/developer-guide.md +++ b/docs/developer-guide.md @@ -110,7 +110,7 @@ You can also modify the compile-time defaults for all `.config` parameters. You 1. Run `make` in the `Firmware` directory. 2. Connect the ODrive via USB and power it up. -3. Flash the firmware using [`odrivetool dfu`](odrivetool#device-firmware-update). +3. Flash the firmware using [odrivetool dfu](odrivetool#device-firmware-update). ### Flashing using an STLink/v2 programmer From 21b54e83686d1ee1f2ea8bf25af04757bbd9702a Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Mon, 25 Jun 2018 20:59:40 -0700 Subject: [PATCH 14/14] python3 ify dfuse error prints --- tools/odrive/dfuse/DfuDevice.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/odrive/dfuse/DfuDevice.py b/tools/odrive/dfuse/DfuDevice.py index e7158d3b..be7d404e 100644 --- a/tools/odrive/dfuse/DfuDevice.py +++ b/tools/odrive/dfuse/DfuDevice.py @@ -156,12 +156,12 @@ class DfuDevice: self.set_address(addr) status = self.wait_while_state(DfuState.DFU_DOWNLOAD_BUSY) if status[1] != DfuState.DFU_DOWNLOAD_IDLE: - raise RuntimeError("An error occured. Device Status: %r" % status) + raise RuntimeError("An error occured. Device Status: {!r}".format(status)) # take device out of DFU_DOWNLOAD_SYNC and into DFU_IDLE self.abort() status = self.wait_while_state(DfuState.DFU_DOWNLOAD_SYNC) if status[1] != DfuState.DFU_IDLE: - raise RuntimeError("An error occured. Device Status: %r" % status) + raise RuntimeError("An error occured. Device Status: {!r}".format(status)) def erase_sector(self, sector): @@ -169,7 +169,7 @@ class DfuDevice: self.erase(sector['addr']) status = self.wait_while_state(DfuState.DFU_DOWNLOAD_BUSY, timeout=sector['len']/32) if status[1] != DfuState.DFU_DOWNLOAD_IDLE: - raise RuntimeError("An error occured. Device Status: %r" % status) + raise RuntimeError("An error occured. Device Status: {!r}".format(status)) def write_sector(self, sector, data): self.set_alternate_safe(sector['alt']) @@ -184,7 +184,7 @@ class DfuDevice: self.write(blocknum, block) status = self.wait_while_state(DfuState.DFU_DOWNLOAD_BUSY) if status[1] != DfuState.DFU_DOWNLOAD_IDLE: - raise RuntimeError("An error occured. Device Status: %r" % status) + raise RuntimeError("An error occured. Device Status: {!r}".format(status)) def read_sector(self, sector): """