Skip to content

Commit

Permalink
Merge pull request #16 from odriverobotics/ros-control
Browse files Browse the repository at this point in the history
Initial ros2_control integration
  • Loading branch information
samuelsadok authored Mar 22, 2024
2 parents 0094044 + 751356f commit 72c2c79
Show file tree
Hide file tree
Showing 44 changed files with 2,551 additions and 84 deletions.
81 changes: 81 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
---
BasedOnStyle: Google
IndentWidth: '4'
ColumnLimit: '120'

IncludeCategories:
# main include automatically assigned to Priority 0
- Regex: '^".*_(conf|config)\.(hpp|h)"$' # config headers
Priority: 3
- Regex: '^".*"$' # sibling & project headers
Priority: 1
- Regex: '^<.*>$' # system & library headers
Priority: 2

# Format function arguments and parameters
BinPackArguments: 'false'
BinPackParameters: 'false'
AllowAllArgumentsOnNextLine: 'false'
AllowAllParametersOfDeclarationOnNextLine: 'false'
AlignAfterOpenBracket: BlockIndent
SpaceBeforeParens: ControlStatements

# Constructor Formatting
PackConstructorInitializers: CurrentLine
IndentAccessModifiers: 'false'
AccessModifierOffset: '-4'
SpaceBeforeCtorInitializerColon: 'true'
BreakConstructorInitializers: BeforeColon
LambdaBodyIndentation: OuterScope

AllowShortCaseLabelsOnASingleLine: 'true'
AllowShortBlocksOnASingleLine: 'false'
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: 'false'
AllowShortEnumsOnASingleLine: 'true'
AllowShortFunctionsOnASingleLine: 'Inline'
AllowShortLambdasOnASingleLine: 'All'

# Switch / Case
IndentCaseLabels: 'true'
IndentCaseBlocks: 'false'

# Preprocessor stuff
AlignConsecutiveMacros: 'true'
AlignEscapedNewlines: Right
AlignTrailingComments: 'false'
SpacesBeforeTrailingComments: 1

# Alignment of procedural code
AlignConsecutiveAssignments: 'false'
AlignConsecutiveDeclarations: 'false'
AlignConsecutiveBitFields: Consecutive

AlignOperands: AlignAfterOperator
# BreakBeforeTernaryOperators: 'false'
BreakBeforeBinaryOperators: 'true'

# Pointers and East/West Const
DerivePointerAlignment: 'false'
PointerAlignment: Left
QualifierAlignment: Leave
# QualifierOrder: ['volatile', 'constexpr', 'static', 'inline', 'type', 'const']

Cpp11BracedListStyle: 'true'

# Vertical Whitespace
SeparateDefinitionBlocks: Leave
EmptyLineBeforeAccessModifier: Always
EmptyLineAfterAccessModifier: Never

# AlignArrayOfStructures: Right
# InsertTrailingCommas: 'Wrapped'


AlwaysBreakAfterReturnType: None
PenaltyReturnTypeOnItsOwnLine: 9999 # We really hate breaking after return types
PenaltyBreakAssignment: 999 # Prefer not to break around =

FixNamespaceComments: 'true'
# NamespaceIndentation: All
...
14 changes: 10 additions & 4 deletions .devcontainer/humble/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@
],
"workspaceMount": "source=${localWorkspaceFolder},target=/${localWorkspaceFolderBasename},type=bind",
"workspaceFolder": "/${localWorkspaceFolderBasename}",
"mounts": [

]
}
"mounts": [],
"customizations": {
"vscode": {
"extensions": [
"ms-vscode.cpptools",
"eamodio.gitlens"
]
}
}
}
30 changes: 30 additions & 0 deletions .devcontainer/iron-remote/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
FROM ros:iron-ros-base

# Add vscode user with same UID and GID as your host system
# (copied from https://code.visualstudio.com/remote/advancedcontainers/add-nonroot-user#_creating-a-nonroot-user)
ARG USERNAME=vscode
ARG USER_UID=1000
ARG USER_GID=$USER_UID
RUN groupadd --gid $USER_GID $USERNAME \
&& useradd -s /bin/bash --uid $USER_UID --gid $USER_GID -m $USERNAME \
&& apt-get update \
&& apt-get install -y sudo \
&& echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \
&& chmod 0440 /etc/sudoers.d/$USERNAME
# Switch from root to user
USER $USERNAME

# Add user to video group to allow access to webcam
RUN sudo usermod --append --groups video $USERNAME

# Update all packages
RUN sudo apt update && sudo apt upgrade -y

# Install Git
RUN sudo apt install -y git

# Rosdep update
RUN rosdep update

# Source the ROS setup file
RUN echo "source /opt/ros/${ROS_DISTRO}/setup.bash" >> ~/.bashrc
19 changes: 19 additions & 0 deletions .devcontainer/iron-remote/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "iron-remote",
"dockerFile": "Dockerfile",
"runArgs": [
"--privileged",
"--network=host"
],
"workspaceMount": "source=/home/pi/odrive_can,target=/${localWorkspaceFolderBasename},type=bind,consistency=cached",
"workspaceFolder": "/${localWorkspaceFolderBasename}",
"mounts": [],
"customizations": {
"vscode": {
"extensions": [
"ms-vscode.cpptools",
"eamodio.gitlens"
]
}
}
}
14 changes: 10 additions & 4 deletions .devcontainer/iron/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@
],
"workspaceMount": "source=${localWorkspaceFolder},target=/${localWorkspaceFolderBasename},type=bind",
"workspaceFolder": "/${localWorkspaceFolderBasename}",
"mounts": [

]
}
"mounts": [],
"customizations": {
"vscode": {
"extensions": [
"ms-vscode.cpptools",
"eamodio.gitlens"
]
}
}
}
4 changes: 3 additions & 1 deletion .github/workflows/ros-build-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,6 @@ jobs:
- name: Run colcon build
run: |
docker run -v ${{ github.workspace }}:/workspace -w /workspace local:${{ matrix.ros-version }} colcon build --packages-select odrive_can
docker run -v ${{ github.workspace }}:/workspace -w /workspace local:${{ matrix.ros-version }} \
/bin/bash -c "rosdep install --from-paths odrive_ros2_control odrive_botwheel_explorer -y --ignore-src && \
colcon build"
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,6 @@
/build/
/install/
/log/

# Python
__pycache__/
18 changes: 18 additions & 0 deletions .vscode/c_cpp_properties.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**",
"/opt/ros/iron/include/hardware_interface",
"/opt/ros/iron/include/rcpputils"
],
"defines": [],
"compilerPath": "/usr/bin/gcc",
"cStandard": "c17",
"cppStandard": "gnu++17",
"intelliSenseMode": "linux-gcc-arm64"
}
],
"version": 4
}
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"C_Cpp.autoAddFileAssociations": false,
}
22 changes: 22 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "build",
"type": "shell",
"command": "colcon build --symlink-install",
"group": {
"kind": "build",
"isDefault": true
},
"presentation": {
"clear": true
},
"problemMatcher": [
"$gcc"
],
},
]
}
84 changes: 13 additions & 71 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,98 +1,40 @@
# ROS2 Package for ODrive

This repository contains a ROS2 node intended for communication with ODrive motor controllers via CAN bus.
This repository contains ROS2 packages for the [ODrive motor controller](https://odriverobotics.com):

For information about installation, prerequisites, and getting started, checkout the ODrive [ROS CAN Package Guide](https://docs.odriverobotics.com/v/latest/guides/ros-package.html).
- **`odrive_node`**: Standalone ROS2 node for communication with ODrives via CAN bus. → [More info](odrive_node/README)
- **`odrive_ros2_control`**: [work in progress] [ros2_control](https://control.ros.org/master/index.html) integration for communication with ODrives via CAN bus.
 → [More info](odrive_ros2_control/README)
- **`odrive_botwheel_explorer`**: Example for using the `odrive_ros2_control` package in the context of the [ODrive BotWheel Explorer](https://odriverobotics.com/shop/botwheel-explorer). → [More info](odrive_botwheel_explorer/README)

Compatible Devices:
`odrive_node` and `odrive_ros2_control` are two alternative approaches and cannot be used at the same time.

For information about installation, prerequisites and getting started, check out the ODrive [ROS CAN Package Guide](https://docs.odriverobotics.com/v/latest/guides/ros-package.html).

## Compatible Devices

- [ODrive Pro](https://odriverobotics.com/shop/odrive-pro)
- [ODrive S1](https://odriverobotics.com/shop/odrive-s1)
- [ODrive Micro](https://odriverobotics.com/shop/odrive-micro)

(not compatible with ODrive 3.x)

System Requirements:
## System Requirements

- Ubuntu >= 20.04
- ROS2 >= Humble


## Interface

### Parameters

* `node_id`: The node_id of the device this node will attach to
* `interface`: the network interface name for the can bus

### Subscribes to

* `/control_message`: Input setpoints for the ODrive.

The ODrive will interpret the values of input_pos, input_vel and input_torque depending on the control mode.

For example: In velocity control mode (2) input_pos is ignored, and input_torque is used as a feedforward term.

**Note:** When changing `input_mode` or `control_mode`, it is advised to set the ODrive to IDLE before doing so. Changing these values during CLOSED_LOOP_CONTROL is not advised.

### Publishes

* `/odrive_status`: Provides ODrive/system level status updates.

For this topic to work, the ODrive must be configured with the following [cyclic messages](https://docs.odriverobotics.com/v/latest/manual/can-protocol.html#cyclic-messages) enabled:

- `error_msg_rate_ms`
- `temperature_msg_rate_ms`
- `bus_voltage_msg_rate_ms`

The ROS node will wait until one of each of these CAN messages has arrived before it emits a message on the `odrive_status` topic. Therefore, the largest period set here will dictate the period of the ROS2 message as well.

* `/controller_status`: Provides Controller level status updates.

For this topic to work, the ODrive must be configured with the following [cyclic messages](https://docs.odriverobotics.com/v/latest/manual/can-protocol.html#cyclic-messages) enabled:

- `heartbeat_msg_rate_ms`
- `encoder_msg_rate_ms`
- `iq_msg_rate_ms`
- `torques_msg_rate_ms`

The ROS node will wait until one of each of these CAN messages has arrived before it emits a message on the `controller_status` topic. Therefore, the largest period set here will dictate the period of the ROS2 message as well.

### Services

* `/request_axis_state`: Sets the axes requested state.

This service requires regular heartbeat messages from the ODrive to determine the procedure result and will block until the procedure completes, with a minimum call time of 1 second.

### Data Types

All of the Message/Service fields are directly related to their corresponding CAN message. For more detailed information about each type, and how to interpet the data, please refer to the [ODrive CAN protocol documentation](https://docs.odriverobotics.com/v/latest/manual/can-protocol.html#messages).

## Using Python Enums

**Python Example Node coming soon!**

In the meantime, here is how you can use the [odrive python package](https://pypi.org/project/odrive/) to display the enums:

from odrive_can.msgs import ControllerStatus # remember to include odrive_can as a package dependency
from odrive.enums import ProcedureResult
... # Node setup
ctrl_stat = ControllerStatus()
... # receive message data
print(ProcedureResult(ctrl_stat.procedure_result))


## Developer Notes

For user instructions, see [this guide](https://docs.odriverobotics.com/v/latest/guides/ros-package.html) instead.
(For user instructions, see [this guide](https://docs.odriverobotics.com/v/latest/guides/ros-package.html) instead.)

You can build this node on a non-ROS developer PC by using the DevContainer configurations in this repository. For example with VSCode:

1. Clone repository
2. Open the repository folder in VSCode. It should automatically present an option "Reopen in Dev Container". Click on that and select the desired ROS version.
3. Once it's re-opened, in the VSCode terminal, run:

```
```bash
colcon build --packages-select odrive_can
source ./install/setup.bash
```
Expand Down
Loading

0 comments on commit 72c2c79

Please sign in to comment.