Merge branch 'devel' into sam_refactoring

This commit is contained in:
Samuel Sadok
2018-04-24 18:05:50 -07:00
4 changed files with 32 additions and 20 deletions
+9 -7
View File
@@ -47,7 +47,7 @@ __CONFIG_UART_PROTOCOL__: Defines which protocol the ODrive should use on the UA
<br><br>
## Downloading and Installing Tools
### Getting a programmer
__Note:__ If you don't plan to make major firmware modifications you can use the built-in DFU feature.
__Note:__ If you have ODrive v3.5 and newer, and don't plan to make major firmware modifications you can use the built-in DFU feature.
In this case you don't need an SWD programmer and you can skip OpenOCD related instructions.
Get a programmer that supports SWD (Serial Wire Debugging) and is ST-link v2 compatible. You can get them really cheap on [eBay](http://www.ebay.co.uk/itm/ST-Link-V2-Emulator-Downloader-Programming-Mini-Unit-STM8-STM32-with-20CM-Line-/391173940927?hash=item5b13c8a6bf:g:3g8AAOSw~OdVf-Tu) or many other places.
@@ -71,9 +71,10 @@ To compile the program, you first need to install the prerequisite tools:
* No additional USB CDC driver should be required on Linux.
#### Mac:
* `brew cask install gcc-arm-embedded`: GCC toolchain+debugger
* `brew cask install osxfuse; brew install tup`: Build tool
* `brew install openocd`: Programmer
First install [Homebrew](https://brew.sh/). Then you can run these commands in Terminal:
* `brew cask install gcc-arm-embedded`: to install GCC toolchain+debugger
* `brew cask install osxfuse; brew install tup`: to install the build tool
* `brew install openocd`: to install the programmer tool
#### Windows:
Install the following:
@@ -94,7 +95,7 @@ After installing all of the above, open a Git Bash shell. Continue at section [B
* Run `make` in the `Firmware` directory.
### Flashing the firmware (standalone device)
Note: ODrive v3.4 and earlier require you to flash with the external programmer first (see below), before you can reflash in standalone mode.
Note: This method of updating the firmware is only supported on ODrive v3.5 and newer. If you have an older board you must instead use the method in the [next section](#flashing-the-firmware).
* __Windows__: Use the [Zadig](http://zadig.akeo.ie/) utility to set ODrive (not STLink!) driver to libusb-win32.
* If 'Odrive version 3.x' is not in the list of devices upon opening Zadig, check 'List All Devices' from the options menu. With the Odrive selected in the device list choose 'libusb-win32' from the target driver list and select the large 'install driver' button.
* Run `make dfu` in the `Firmware` directory.
@@ -165,6 +166,7 @@ pip install pyusb pyserial
* If 'Odrive version 3.x' is not in the list of devices upon opening Zadig, check 'List All Devices' from the options menu. With the Odrive selected in the device list choose 'libusb-win32' from the target driver list and select the large 'install driver' button.
6. Open the bash prompt in the `ODrive/tools/` folder.
7. Run `python3 odrive_demo.py` or `python3 odrivetool`.
- __Mac__: instead run: `python3 odrive_demo.py --discover serial` or `python3 explore_odrive.py --discover serial`
- `odrive_demo.py` is a very simple script which will make motor 0 turn back and forth. Use this as an example if you want to control the ODrive yourself programatically.
- `odrivetool` drops you into an interactive python shell when started without any arguments. There you can explore and edit the parameters that are available on your device. For instance `odrv0.motor0.pos_setpoint = 10000` makes motor0 move to position 10000. To connect over serial instead of USB run `./tools/odrivetool --path serial`. Run `./tools/odrivetool --help` to see what else you can do with the script.
@@ -250,7 +252,7 @@ If you have an encoder with an index (Z) signal, you may avoid having to do the
* Since you will only do this once, it is recommended that you mechanically disengage the motor from anything other than the encoder, so it can spin freely.
* All the parameters we will be modifying are in the motor structs at the top of [MotorControl/low_level.c](MotorControl/low_level.c).
* Set `.encoder.use_index = true` and `.encoder.calibrated = false`.
* Set `.encoder.use_index = true` and `.encoder.manually_calibrated = false`.
* Flash this configuration, and let the motor scan for the index pulse and then complete the encoder calibration.
* Run `odrivetool`, check [Communicating over USB or UART](#communicating-over-usb-or-uart) for instructions on how to do that.
* Enter the following to print out the calibration parameters (substitute the motor number you are calibrating for `<NUM>`):
@@ -258,7 +260,7 @@ If you have an encoder with an index (Z) signal, you may avoid having to do the
* `odrv0.motor<NUM>.encoder.motor_dir` - This should print 1 or -1.
* Copy these numbers to the corresponding entries in low_level.c: `.encoder.encoder_offset` and `.encoder.motor_dir`.
* _Warning_: Please be careful to enter the correct numbers, and not to confuse the motor channels. Incorrect values may cause the motor to spin out of control.
* Set `.encoder.calibrated = true`.
* Set `.encoder.manually_calibrated = true`.
* Flash this configuration and check that the motor scans for the index pulse but skips the encoder calibration.
* Congratulations, you are now done. You may now attach the motor to your mechanical load.
* If you wish to scan for the index pulse in the other direction (if for example your axis usually starts close to a hard-stop), you can set a negative value in `.encoder.idx_search_speed`.
+1 -1
View File
@@ -66,7 +66,7 @@ ODrive v3.3 and onward have 5V tolerant GPIO pins.
To enable step/dir mode for the GPIO, please see [Setting the GPIO mode](Firmware/README.md#communication-configuration).
There is also a new config variable called `counts_per_step`, which specifies how many encoder counts a "step" corresponds to. It can be any floating point value.
The maximum step rate is pending tests, but it should handle at least 16kHz. If you want's to test it, please be aware that the failure mode on too high step rates is expected to be that the motors shuts down and coasts.
The maximum step rate is pending tests, but it should handle at least 32kHz. If you want's to test it, please be aware that the failure mode on too high step rates is expected to be that the motors shuts down and coasts.
Please be aware that there is no enable line right now, and the step/direction interface is enabled by default, and remains active as long as the ODrive is in position control mode. By default the ODrive starts in position control mode, so you don't need to send any commands over USB to get going. You can still send USB commands if you want to.
+21 -11
View File
@@ -206,7 +206,7 @@ def show_deferred_message(message, cancellation_token):
t.daemon = True
t.start()
def put_odrive_into_dfu_mode(my_drive):
def put_odrive_into_dfu_mode(my_drive, cancellation_token):
"""
Puts the specified device into DFU mode
"""
@@ -216,15 +216,23 @@ def put_odrive_into_dfu_mode(my_drive):
"DFU with this script should work fine."
.format(my_drive.__channel__.usb_device.serial_number))
return
print("Putting device {} into DFU mode...".format(my_drive.__channel__.usb_device.serial_number))
try:
my_drive.enter_dfu_mode()
except odrive.protocol.ChannelBrokenException as ex:
pass # this is expected because the device reboots
if platform.system() == "Windows":
show_deferred_message("Still waiting for the device to reappear.\n"
"Use the Zadig utility to set the driver of 'STM32 BOOTLOADER' to libusb-win32.",
find_odrive_cancellation_token)
hw_version_major = my_drive.hw_version_major if hasattr(my_drive, 'hw_version_major') else 3
hw_version_minor = my_drive.hw_version_minor if hasattr(my_drive, 'hw_version_minor') else 4
if hw_version_major == 3 and hw_version_minor >= 5:
print("Putting device {} into DFU mode...".format(my_drive.__channel__.usb_device.serial_number))
try:
my_drive.enter_dfu_mode()
except odrive.protocol.ChannelBrokenException:
pass # this is expected because the device reboots
if platform.system() == "Windows":
show_deferred_message("Still waiting for the device to reappear.\n"
"Use the Zadig utility to set the driver of 'STM32 BOOTLOADER' to libusb-win32.",
cancellation_token)
else:
print("Found device {}".format(my_drive.__channel__.usb_device.serial_number))
print(" DFU mode is not supported on board version 3.4 or earlier.")
print(" This is because entering DFU mode on such a device would")
print(" break the brake resistor FETs under some circumstances.")
def launch_dfu(args, app_shutdown_token):
"""
@@ -251,7 +259,9 @@ def launch_dfu(args, app_shutdown_token):
# Scan for ODrives not in DFU mode and put them into DFU mode once they appear
# We only scan on USB because DFU is only possible over USB
odrive.discovery.find_all(args.path, serial_number, put_odrive_into_dfu_mode, find_odrive_cancellation_token, app_shutdown_token)
odrive.discovery.find_all(args.path, serial_number,
lambda dev: put_odrive_into_dfu_mode(dev, find_odrive_cancellation_token),
find_odrive_cancellation_token, app_shutdown_token)
# Poll libUSB until a device in DFU mode is found
while not app_shutdown_token.is_set():
+1 -1
View File
@@ -251,7 +251,7 @@ class Channel(PacketSink):
self._printer("receiver thread is exiting: " + traceback.format_exc())
finally:
self._channel_broken.set()
threading.Thread(target=receiver_thread, daemon=True).start()
threading.Thread(target=receiver_thread).start()
def remote_endpoint_operation(self, endpoint_id, input, expect_ack, output_length):
if input is None: