A complete firmware stack for the Poulpe boards in combination with Venouse boards, using the Rust programming language and the Embassy-rs framework. The firmware is designed to work with the Orbita2d and Orbita3d actuator setups.
- Installation
- Build and program
- Firmware architecture
- Firmware configuration
- Safety features
- Firmware state machine
- LED blinking patterns
- Related repositories
In order to build and flush this firmware to the boards there are two main pre-requisites:
- Rust toolchain installed on your computer
bootloader_Pouple
already flushed to the board - see the bootloader repo
rustup default nightly
rustup update
rustup target add thumbv7em-none-eabihf
cargo install probe-rs --features cli
- Setup the st-link v2 device permisions: more info in probe docs
(You might want to install probe-rs v0.21.1:
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/probe-rs/probe-rs/releases/download/v0.21.1/probe-rs-installer.sh | sh
)
See how to install the bootloader on the board in the bootloader repo
In short
- Clone the repository
git clone [email protected]:pollen-robotics/bootloader_Poulpe.git` cd bootloader_Poulpe
- Flush the bootloader to the board
cargo flash --release --chip STM32H743VGTx
Once this is done you can proceed with the firmware installation.
Clone the repository and navigate to the root of the repository.
git clone [email protected]:pollen-robotics/firmware_Poulpe.git
Use the desired fimrware version
For exmaple, to use the v0.9.0 version
cd firmware_Poulpe
git checkout v0.9.0
Then run the following command to build the firmware:
cargo build --release --features # hardware version ex. orbita3d_beta
Version | orbita2d | orbita3d | Communication | Hardware |
---|---|---|---|---|
BETA | orbita2d_beta |
orbita3d_beta |
dynamixel | Poulpe + Sponge + TMC4671+TMC6100 BOB |
DVT | orbita2d_gamma |
orbita3d_gamma |
EtherCAT | Poulpe 2d + Ventouse 2d or Poulpe 3d + Ventouse 3d |
PVT | orbita2d_pvt |
orbita3d_pvt |
EtherCAT | Poulpe 2d + Ventouse 2d or Poulpe 3d + Ventouse 3d |
Note: The first build will take a long time because it will download the dependencies and compile them.
There are two ways of flushing the firmware to the board:
Type | Pros | Cons |
---|---|---|
USB Stlink based flashing | ✅ Debugging and logging ✅ Has to be used for the first flash ✅ No firmware corruption possible |
❌ One board at the time ❌ You need the Stlink ❌ Connector hard to access |
EtherCAT FoE firmware upload | ✅ No special hardware ✅ All borads at once |
❌ No debugging output ❌ Only for the firmware update ❌ Can result in the board bricking |
- Make sure that the bootloader is already flushed to the board
- Make sure that the stlink is connected to the board and to the computer
- Make sure that you selected the proper version of your hardware as indicated in the table above
- Run the command to flush the board:
ex.
cargo run --release --features orbita2d_beta
This command will build the firmware and flash it to the board, and then it will start the firmware.
Debugging output
Optionally you can add theDEFMT_LOG
environment variable to see the logsDEFMT_LOG=debug cargo run --release --features orbita2d_pvt
trace
or info
. For the release version, the logs should be disbled, set the DEFMT_LOG
to off
DEFMT_LOG=off cargo run --release --features orbita2d_pvt
See the full guide on how to flash the entire robot.
-
Make sure that the bootloader is already flushed to the board
-
Make sure that the firmware is version v1.5 or higher
-
Make sure that the ehterca tool is installed on your computer
ethercat master
- installation guide -
Make sure that the board is connected to the EtherCAT network
ethercat slaves
- to see the connected slaves -
Build your firmware for example:
cargo build --release --features orbita2d_pvt
-
Extract the firmware binary using
extract_hex
scriptsh firmware_update_scripts/extract_hex.sh
Example output
> sh firmware_update_scripts/extract_hex.sh Bin file generated: firmware.bin
-
Upload the firmware to the board using the
update_firmware
scriptsh firmware_update_scripts/update_firmware.sh firmware.bin 0 # slave id
Example output
> sh firmware_update_scripts/update_firmware.sh firmware.bin 0 Starting firmware update for slave 0 with firmware.bin... Writing firmware... Read 22152 bytes of FoE data. FoE writing finished. Verifying bytes received... Firmware size: 22152 Bytes received: 22152 Confirming firmware update... Firmware update completed successfully
The step 7) can be done only once, and if you try to update the firmware the second time, you will receive an error
Failed to write via FoE: FOE_ACK_ERROR
. In order to upload the new firmware you have to reset the board. This is a safety feature to avoid the firmware corruption.
Manually upload the firmware to the board (avoid the step 7)
Instead of using the update_firmware_ethercat
script you can manually upload the firmware to the board using the ethercat
tool.
IMPORTANT!!! Next steps are critical and can result in the board being bricked if not properly followed! Make sure to follow the procedure exactly
-
Flash the firmware to the board
ethercat foe_write -p0 firmware.bin --verbose
> ethercat foe_write -p0 firmware.bin --verbose Read 124320 bytes of FoE data. FoE writing finished.
-
Send the exact number of bytes written to the firmware to the board on the address
0x1000
and subindex1
using the SDO protocolethercat download -p0 0x100 1 -t uint32 # number of bytes ex. 124320
You can find the number of bytes of the file with
stat -c %s firmware.bin
If this step has went well the board will reboot and the new firmware will be loaded.
The software is divided into a few main rust modules:
sensors
- module implementing the communication with the sensors - read moremotor_control
- module implementing the motor control - read moreconfig
- module unifying the configuration of the firmware - read moreethercat
- module implementing the EtherCAT communication - read moredynamixel
- module implementing the Dynamixel communication - read morestate_machine
- module implementing the state machine of the board and the safety features - read moreutils
- module implementing the utility functions - read morebin
- module implementing a set of test and benchmark programs that can be run on the board - read more
The main firmware is implemented in the main.rs
file.
The firmware is composed into two real-time tasks that communicate through the shared_memory
module. The two tasks are:
-
control_loop
- responsible for the motor control and sensor reading- inialization of the motor control and sensor reading
- communication with the low-level TMC4671 actuators using SPI
- reading the motor position sensors
- reading the motor and board temperatures
- ensuring the safety of the motor by monitoring the temperatures, voltages low-level errors etc.
-
message_handler
- responsible for the communication with the host computer either- using the serial communication and Dynamixel protocol -
dynamixel
- using EtherCAT protocol -
ethercat
- choosing the communication protocol is done using the
features
(eitherethercat
ordynamixel
)
- using the serial communication and Dynamixel protocol -
Orbita2d is a robotic actuator with two motors that use differential drive to run two axis. The motors used are maxon flat motors of Maxon EC45
series.
There are three differnet versions of the Orbita2d setup: beta, DVT and PVT. The main differences between the versions are the motor control board and the communication protocol used.
version | control board | driver control board | motor | communication | temperature sensing | axis sensor communication |
---|---|---|---|---|---|---|
beta | poulpe | TMC4671 + TMC6100 BOB | EC45 flat | dynamixel | motor B | SPI |
DVT | poulpe2d | ventouse2d | EC45 flat | EtherCAT | motor B | SPI |
PVT | poulpe2d | ventouse2d | EC45 flat | EtherCAT | both motors | Differential I2C LTC4332 |
Orbita3d is a robotic actuator with three motors that use a parallel mechanical structure drive to run three axis. The motors used are maxon motors of the Maxon ECX22
series.
There are three differnet versions of the Orbita3d setup: beta, DVT and PVT.
version | control board | driver control board | motor | communication | temperature sensing | axis sensor communication |
---|---|---|---|---|---|---|
beta | poulpe | TMC4671 + TMC6100 BOB | ECX22 M | dynamixel | motor TOP | SPI, I2C |
DVT | poulpe3d | ventouse3d | ECX22 M | EtherCAT | motor TOP | SPI, I2C |
PVT | poulpe3d | ventouse3d | ECX22 L | EtherCAT | all three motors | Differential link LTC4332(SPI) LTC4331(I2C) |
The same firmware can be configured to work with many different Orbita2d and Orbita3d hardware setups from which the most important are the beta, DVT and PVT versions. The configutation can be done using the Cargo.toml
file and the command line arguments --featatures
.
Version | orbita2d | orbita3d | Communication | Hardware |
---|---|---|---|---|
BETA | orbita2d_beta |
orbita3d_beta |
dynamixel | Poulpe + Sponge + TMC4671+TMC6100 BOB |
DVT | orbita2d_gamma |
orbita3d_gamma |
EtherCAT | Poulpe 2d + Ventouse 2d or Poulpe 3d + Ventouse 3d |
PVT | orbita2d_pvt |
orbita3d_pvt |
EtherCAT | Poulpe 2d + Ventouse 2d or Poulpe 3d + Ventouse 3d |
Orbita2d and Orbita3d setups can be configured using the following features (one of them has to be set):
orbita2d
- Orbita2d actuator setup - github pageorbita3d
- Orbita3d actuator setup - github page
Electronics version The electronics version determins the motor control board used and the communication protocols to the sensors
beta
- beta electronics versiongamma
- DVT electronics versionpvt
- PVT electronics version
One them has to be set
Motor version The motor version determins the gearing ratio and motor parameters used in the fimrware for the motor control
ec60
- EC60 flat maxon motor used - datasheetec45
- EC45 flat maxon motor used - datasheetecx22
- ECX22 maxon motor used - datasheet
One them has to be set
Communication configuration features
There are two supported communication protocoles and each can be enabled using its dedicated feature
ethercat
- EtherCAT communicationdynamixel
- dynamixel communication
One them has to be set
They cannot be used both at the same time. At least one of them has to be used in order to be able to talk to the poulpe board.
Advanced control features These features are used to configure the advanced control features in order to improve the motor control performance
cmd_filter
- Filter received position commands to reduce the jerk of the motorvelocity_feedforward
- Enable the use of the velocity feedforward to improve the velocity tracking performance- has to be used in conjunction with the appropriate dynamixel message
- using this feature will not change the default behavior of the firmware
allow_mode_change
- Allow the mode change of the motor control. Default mode is the position mode, and if this feature is enabled the motor can be switched to the velocity mode or to torque mode
Actuator output features These features are used to decide which output angle of the motor to control
gearbox_output
- Control the motor angle after the gearboxaxis_output
- Control the motor angle after the gearbox and axis reduction
Safety features Used to configure the safety features of the board
no_temperature_sensor
- The board does not have a temperature sensor, avoid reading it and using it for safetyignore_errors
- Ignore the safety errors and continue the operationallow_quickstop
- Allow the quickstop state of the actuator, a software emergency stop
Flash memory features Used to enable/disable the usage of the flash memory
use_flash
- Enable the usage of the flash memorywrite_flash
- Write the configuration to the flash memory (if not used the configuration will be read from flash - if available)
Debugging features Used to enable the debugging features
debug_execution_time
- Measure and display the execution time of the real-time tasks
In order to use the absolute zero position of the actuators the absolute zero values need to be writen to the flash memory of the poulpe boards. These values are written to the memory once and are used on the boot of the board. The absolute zeros can be set using the ZEROS
command line argument. The values are written to the flash memory using the write_flash
feature.
The orbita2d and 3d actuators have dedicated absolute sensors for each axis that are used for their positioning. In order to provide the firmware with the mechanical zero position of the actuators, the axis sensors' position at the mechanical zero position has to be set. These values are written to the FLASH memory and require to be set only once.
There are couple of ways to set the axis zeros:
- Directly from the terminal to the firmware using the
ZEROS
command line argument (in combination withwrite_flash
feature) - Using the provided binary files in the
src/bin
folder
The binary files are specific to the actuator type
bench_Orbita2dWriteZeros.rs
- for the orbita2d actuatorbench_Orbita3dWriteZeros.rs
- for the orbita3d actuator
The binary files read the current axis positions and write them to the flash memory directly. No need to set the ZEROS
command line argument.
To write the zeros to the flash memory use the following command (example PVT
version of the orbita2d)
cargo run --release -bin bench_Orbita2dWriteZeros --features orbita2d_pvt
Then just flash the firmware to the board and the zeros will be read from the flash memory on the next boot.
cargo run --release --features orbita2d_pvt
IMPORTANT! The binary programs
bench_OrbitaXdWriteZeros
will write current axis sensor values as the axis zeros to the flash memory on each run. So make sure to run them only once and make sure to flash the firmware to the board right after the zeros are written to the flash memory.
-
This way of flashing the axis zeros requires you to have determined the axis zero positions values determined in advance
-
To write the configuration to the flash memory use the
write_flash
feature and set the command line argumentsZEROS
to the desired values. The configuration will be written to the flash memory and will be read from it on the next boot.
ZEROS=0.12,0.34,0.56 cargo run --release --features "orbita3d_xvz,write_flash"
- Once the configuration is written to the flash memory the
write_flash
feature can be removed as well as the command line arguments. The firmaware will automatically read the configuration from the flash memory on the next boot.
cargo run --release --features orbita3d_xvz # the configuration will be read from the flash memory
- To reset the configuration in the flash memory use the
write_flash
feature and dont set any command line arguemnts. The configuration will be reset to the default values.
cargo run --release --features "orbitaNd_xvz,write_flash"
So here is an example suggested workflow:
- Set the desired configuration using the command line arguments and the
write_flash
feature
ZEROS=0.12,0.34,0.56 cargo run --release --features "orbita3d_beta,write_flash"
- Remove the
write_flash
feature and the command line arguments for any other upload of the firmware in the future
cargo run --release --features orbita3d_beta
Poulpe boards have to be configured as EtherCAT slaves in order to work with the EtherCAT master. The slave configuration is done using ESI XML files where the PDO, SDO and FoE protocols are defined. These files are compiled to the bunary format and written to the EEPROM memory of the LAN9252 chip, using the ethercat
tool. The configuration is done only once and is stored in the EEPROM memory.
See a bit mode information in the ethercat module
The firmware has implemented several safety features to ensure the safety of the motor and the user. The safety features are implemented in the motor_control
module and are executed in the control_loop
real-time task. The safety features are:
Safe startup and checks
- Check that the low-level drivers are working properly
- Check that the absolute sensors are working properly
- Check that the motor moves freely and is not blocked
Only if all the checks are passed the board will pass the initialization and will be ready to be switched on.
Real-time safety monitoring
- Motor temperature monitoring (high temperature warning at 65°C, high temperature error at 75°C)
- Board temperature monitoring (high temperature warning at 65°C, high temperature error at 75°C)
- Low-level driver failure monitoring
- Absolute sensor error monitoring
- Bus voltage monitoring (error under 10V)
- Low-level driver and sensor communication monitoring (error if the communication is lost for more thant 1s)
- Over-temperature protection (not implemented yet)
The poulpe will stop disable the motors if any of the safety checks failed are triggered.
The state machine of the poulpe board is implemented in the state_machine
module. The state machine is responsible for the initialization of the board and the safety features. The state machine follows the CiA 402 standard for the motor control.
The state machine has the following states:
NotReadyToSwitchOn
- The board is performing the initializationSwitchOnDisabled
- The init is done successfully and the board is disabledReadyToSwitchOn
- The board is ready to be switched onSwitchedOn
- The board is switched onOperationEnabled
- The board is switched on and the actuators are enabledQuickStopActive
- The board is responding to the quick stop command (emergency stop)- once the response is done the firmware goes to the
SwitchOnDisabled
state
- once the response is done the firmware goes to the
FaultReactionActive
- The board is in the fault reaction state (one of the safety checks failed)- once the response is done the firmware goes to the
Fault
state
- once the response is done the firmware goes to the
Fault
- The board is in the fault state (not recoverable error)
There is an additional warning flag that can be active if the board or motor temperatures are high, but still under the maximum allowed value. The warning flag is active in the SwitchedOn
and OperationEnabled
states.
Read more in the state machine module
The blinking of the LED on the board is used to indicate the state of the board. There are two colors of the LED - green and red. The LED can be solid or blinking. The LED is blinking with a period of 500ms. The pattern of blinking is as follows:
state | CiA402 state | green | red |
---|---|---|---|
init | NotReadyToSwitchOn |
blinks | blinks |
preop | SwitchOnDisabled ,ReadyToSwitchOn ,SwitchedOn |
solid | off |
preop + warning | SwitchOnDisabled ,ReadyToSwitchOn ,SwitchedOn |
solid | blinks |
op | OperationEnabled |
solid | off |
op + warning | OperationEnabled |
solid | blinks |
fault | Fault |
off | solid |
fault_reaction | FaultReactionActive |
off | blinks |
quick_stop_reaction | QuickStopActive |
solid | solid |
This firmware repo is closely related to different software and hardware repositories.
- bootloader_Poulpe - A bootloader for the Poulpe board
- poulpe_ethercat_controller - The complete EtherCAT master stack for the Poulpe boards
- orbita2d_control - The orbita2d control software
- orbita3d_control - The orbita3d control software
The firmware implmenets the ethercat slave and the master is implemented in the poulpe_ethercat_controller
repository. Therefore the compatibility between the firmware and the poulpe_ethercat_controller
is important and is as follows:
firmware_poulpe version |
poulpe_ethercat_controller version |
---|---|
v0.9.0 | v0.9.0 or higher |
v1.0.x | v1.0.x or higher |
v1.5.x | v1.5.x |
So in general, the poulpe_ethercat_controller
version has to be the same or higher than the firmware_poulpe
version. See available poulpe_ethercat_controller
releases here. More details about the master-slave communicaiton protocol can be found in the ethercat crate README.md
- elec_Poulpe - The Poulpe board (
beta
version) - elec_Sponge - The driver board (
beta
version) - elec_Poulpe_2d - The Poulpe board for orbita2d (
DVT
andPVT
versions) - elec_Ventouse_2d - The Ventouse board for orbita2d (
DVT
andPVT
versions) - elec_Poulpe_3d - The Poulpe board for orbita3d (
DVT
andPVT
versions) - elec_Ventouse_3d - The Ventouse board for orbita3d (
DVT
andPVT
versions)
- Safety
- Make more accurate motor temperature reading
- Add over-current protection
- Testing - initial developement
- Add unit tests
- Add integration tests
- Add hardware tests