Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 16 additions & 63 deletions ros2/.devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,26 +1,5 @@
# TODO: Update the base image to ros:humble-ros-base as soon as updated GPG keys are available
FROM ubuntu:22.04
FROM ros:humble-ros-base

ENV DEBIAN_FRONTEND=noninteractive
ENV LANG=en_US.UTF-8
ENV LC_ALL=en_US.UTF-8

# Install ros:humble-ros-base
RUN apt-get update && apt-get install -y \
locales software-properties-common curl && \
locale-gen en_US en_US.UTF-8 && \
update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 && \
add-apt-repository universe && \
export ROS_APT_SOURCE_VERSION=$(curl -s https://api.github.com/repos/ros-infrastructure/ros-apt-source/releases/latest | grep -F "tag_name" | awk -F\" '{print $4}') && \
curl -L -o /tmp/ros2-apt-source.deb "https://github.com/ros-infrastructure/ros-apt-source/releases/download/${ROS_APT_SOURCE_VERSION}/ros2-apt-source_${ROS_APT_SOURCE_VERSION}.$(. /etc/os-release && echo $VERSION_CODENAME)_all.deb" && \
apt-get install -y /tmp/ros2-apt-source.deb && \
apt-get update && apt-get install -y --fix-missing ros-humble-desktop && \
apt-get clean && rm -rf /var/lib/apt/lists/* && \
echo "source /opt/ros/humble/setup.bash" >> /etc/bash.bashrc

# END of TODO

# Install dependencies
RUN apt-get update && apt-get install -y \
# Install libfranka build depencencies
build-essential \
Expand All @@ -29,45 +8,13 @@ RUN apt-get update && apt-get install -y \
libeigen3-dev \
libfmt-dev \
libpoco-dev \
# Install ros packages
libignition-gazebo6-dev \
libignition-plugin-dev \
ros-humble-ament-cmake-clang-format \
ros-humble-ament-cmake-clang-tidy \
ros-humble-backward-ros \
ros-humble-control-msgs \
ros-humble-controller-interface \
ros-humble-controller-manager \
ros-humble-generate-parameter-library \
ros-humble-hardware-interface \
ros-humble-hardware-interface-testing \
ros-humble-joint-state-broadcaster \
ros-humble-joint-state-publisher \
ros-humble-joint-state-publisher-gui \
ros-humble-joint-trajectory-controller \
ros-humble-moveit-kinematics \
ros-humble-moveit-planners-ompl \
ros-humble-moveit-ros-move-group \
ros-humble-moveit-ros-visualization \
ros-humble-moveit-simple-controller-manager \
ros-humble-pinocchio \
ros-humble-realtime-tools \
ros-humble-ros2-control-test-assets \
ros-humble-ros2-controllers \
ros-humble-ros2controlcli \
ros-humble-rviz2 \
ros-humble-sdformat-urdf \
ros-humble-xacro \
# Install python3 packages
python3-colcon-common-extensions\
# Install ros packages
python3-colcon-common-extensions \
python3-colcon-mixin \
python3-pip \
&& rm -rf /var/lib/apt/lists/* \
&& pip3 install -U dynamixel_sdk \
tyro \
vcstool \
black

python3-vcstool \
&& rm -rf /var/lib/apt/lists/*

# Install libfranka
ARG LIBFRANKA_VERSION=0.15.0
Expand All @@ -85,17 +32,20 @@ RUN /bin/bash -c "source /opt/ros/humble/setup.bash && \
# Install franka_ros2
ARG FRANKA_ROS2_VERSION=v1.0.0
ARG FRANKA_DESCRIPTION_VERSION=0.4.0
RUN /bin/bash -c 'source /opt/ros/humble/setup.bash && \
RUN /bin/bash -c 'source /opt/ros/humble/setup.bash && \
mkdir -p /tmp/franka_ros2 && cd /tmp/franka_ros2 && \
git clone --recursive https://github.com/frankaemika/franka_ros2.git --branch ${FRANKA_ROS2_VERSION} && \
git clone --recursive https://github.com/frankaemika/franka_description.git --branch ${FRANKA_DESCRIPTION_VERSION} &&\
git clone --recursive https://github.com/frankaemika/franka_description.git --branch ${FRANKA_DESCRIPTION_VERSION} && \
apt-get update && \
rosdep update && \
rosdep install --from-paths . --ignore-src -r -y && \
rm -rf /var/lib/apt/lists/* && \
colcon build --install-base /opt/ros/humble/franka --cmake-args -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=off && \
cd .. &&\
cd .. && \
rm -rf /tmp/franka_ros2 && \
echo "source /opt/ros/humble/franka/setup.bash" >> ~/.bashrc &&\
echo "source /opt/ros/humble/franka/setup.bash" >> ~/.bashrc && \
echo "source /opt/ros/humble/franka/setup.sh" >> ~/.profile'


# Install robotiq gripper
ARG ROS2_ROBOTIQ_GRIPPER_COMMIT_HASH="2ff85455d4b9f973c4b0bab1ce95fb09367f0d26"
RUN /bin/bash -c "source /opt/ros/humble/setup.bash && \
Expand All @@ -105,6 +55,9 @@ RUN /bin/bash -c "source /opt/ros/humble/setup.bash && \
cd ros2_robotiq_gripper && git checkout ${ROS2_ROBOTIQ_GRIPPER_COMMIT_HASH} && cd .. && \
sed -i 's/kGripperMaxSpeed = 0.150;/kGripperMaxSpeed = 1.0;/g' ros2_robotiq_gripper/robotiq_driver/src/hardware_interface.cpp && \
vcs import . --input ros2_robotiq_gripper/ros2_robotiq_gripper.humble.repos && \
apt-get update && \
rosdep update && \
rosdep install --from-paths . --ignore-src -r -y && \
colcon build --install-base /opt/ros/humble/franka --cmake-args -DCMAKE_BUILD_TYPE=Release && \
cd .. && \
rm -rf tmp_build && \
Expand Down
2 changes: 1 addition & 1 deletion ros2/.devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,5 @@
},
"workspaceFolder": "/workspace/",
"shutdownAction": "stopCompose",
"postCreateCommand": "echo \"source /workspace/install/setup.bash \">> ~/.bashrc"
"postCreateCommand": "/bin/bash /workspace/ros2/install_workspace_dependencies.bash && echo 'source /workspace/ros2/install/setup.bash' >> ~/.bashrc"
}
9 changes: 2 additions & 7 deletions ros2/.devcontainer/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,6 @@ services:
restart: no
network_mode: host
volumes:
- ../:/workspace
- ../../gello/dynamixel/driver.py:/workspace/src/franka_gello_state_publisher/franka_gello_state_publisher/driver.py
- ../../:/workspace
- /dev/serial/by-id:/dev/serial/by-id
# GELLO Calibration Files
- ../../scripts/gello_get_offset.py:/workspace/gello_get_offset.py
- ../../gello/dynamixel:/workspace/gello/dynamixel
# Python flake8 config
- ../../.flake8:/workspace/.flake8

33 changes: 29 additions & 4 deletions ros2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,31 @@ This package provides a ROS 2 node for managing the gripper connected to the Fra

## VS-Code Dev-Container

We recommend working inside the provided VS-Code Dev-Container for a seamless development experience. Dev-Containers allow you to use a consistent environment with all necessary dependencies pre-installed. For more information, refer to the [VS-Code Dev-Containers documentation](https://code.visualstudio.com/docs/devcontainers/containers).
We recommend working inside the provided VS-Code Dev-Container for a seamless development experience. Dev-Containers allow you to use a consistent environment with all necessary dependencies pre-installed.

If you choose not to use the Dev-Container, you will need to manually install the dependencies listed in the `Dockerfile` located in the `.devcontainer` folder.
To start the Dev-Container, open the `ros2` sub-folder of this repository (not the entire `gello_software` folder) in VS Code. If prompted, select **"Reopen in Container"** to launch the workspace inside the Dev-Container. If you are not prompted, open the Command Palette (`Ctrl+Shift+P`) and select **"Dev Containers: Reopen in Container"**. Building the container for the first time will take a few minutes. For more information, refer to the [VS-Code Dev-Containers documentation](https://code.visualstudio.com/docs/devcontainers/containers).

If you choose not to use the Dev-Container, please refer to the [Local Setup](#local-setup) section below for manual installation instructions.

## Local Setup

### Prerequisites

- **ROS 2 Humble Desktop** must be installed.
See the [official installation guide](https://docs.ros.org/en/humble/Installation.html) for instructions.
- **libfranka** and **franka_ros2** must be installed.
Refer to the [Franka Robotics documentation](https://frankaemika.github.io/docs/index.html) for installation steps and compatibility information.
- **ros2_robotiq_gripper** (if required) must be installed.
See the [ros2_robotiq_gripper GitHub repository](https://github.com/PickNikRobotics/ros2_robotiq_gripper) for installation and usage instructions.

> 💡 **Hint:**
> You can also find example installation commands for `libfranka`, `franka_ros2`, and `ros2_robotiq_gripper` in the [Dockerfile](./.devcontainer/Dockerfile) located in the `ros2/.devcontainer` directory. These commands can be copy-pasted for your local setup.

### Further Dependency Installations

After installing the prerequisites, you may need to install additional dependencies required by this workspace. For this you can run the `install_workspace_dependencies.bash` script.

If you add new dependencies to your packages, remember to update the relevant `requirements.txt`, `requirements_dev.txt` or `package.xml` files and re-run the script.

## Build and Test

Expand All @@ -59,6 +81,9 @@ The packages come with a set of tests, which can be executed using the following
colcon test
```

> ⚠️ **Important:**
> All commands for building and testing must be executed from the `ros2` directory of this repository.

## Getting Started

### 1. **Run the GELLO Publisher**
Expand All @@ -83,7 +108,7 @@ In this case, the `GELLO_USB_ID` would be `/dev/serial/by-id/usb-FTDI_USB__-__Se
If not done already, follow the instructions of the `Create the GELLO configuration and determining joint ID's` section in the main README.md. Use the provided script to configure the GELLO for Franka FR3:

```bash
python3 gello_get_offset.py \
python3 scripts/gello_get_offset.py \
--start-joints 0 0 0 -1.57 0 1.57 0 \
--joint-signs 1 1 1 1 1 -1 1 \
--port /dev/serial/by-id/<GELLO_USB_ID>
Expand Down Expand Up @@ -127,7 +152,7 @@ ros2 launch franka_gello_state_publisher main.launch.py com_port:=/dev/serial/by

- **For the Robotiq 2F-85**:
```bash
ros2 launch franka_gripper_manager robotiq_gripper_controller_client.launch.py com_port:=<ROBOTIQ_USB_ID>
ros2 launch franka_gripper_manager robotiq_gripper_controller_client.launch.py com_port:=/dev/serial/by-id/<ROBOTIQ_USB_ID>
```

The `ROBOTIQ_USB_ID` can be determined by `ls /dev/serial/by-id`.
Expand Down
9 changes: 9 additions & 0 deletions ros2/install_workspace_dependencies.bash
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/bash
set -e

pip3 install -r ros2/requirements.txt
pip3 install -r ros2/requirements_dev.txt

apt-get update
rosdep update
rosdep install --from-paths ros2 --ignore-src -r -y
2 changes: 2 additions & 0 deletions ros2/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
dynamixel_sdk
tyro
1 change: 1 addition & 0 deletions ros2/requirements_dev.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
black
4 changes: 2 additions & 2 deletions ros2/src/franka_fr3_arm_controllers/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ if(BUILD_TESTING)
ament_cppcheck(${CPP_DIRECTORIES})
ament_lint_cmake(CMakeLists.txt)
ament_xmllint()
ament_clang_format(CONFIG_FILE /workspace/.clang-format ${CPP_DIRECTORIES})
ament_clang_format(CONFIG_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../../.clang-format ${CPP_DIRECTORIES})
ament_copyright(${CPP_DIRECTORIES} package.xml)

ament_add_gtest(
Expand All @@ -125,7 +125,7 @@ endif()

if(CHECK_TIDY)
find_package(ament_cmake_clang_tidy REQUIRED)
set(ament_cmake_clang_tidy_CONFIG_FILE /workspace/.clang-tidy)
set(ament_cmake_clang_tidy_CONFIG_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../../.clang-tidy)
ament_clang_tidy(${CMAKE_BINARY_DIR})
endif()

Expand Down
5 changes: 3 additions & 2 deletions ros2/src/franka_fr3_arm_controllers/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@
<depend>controller_interface</depend>
<depend>pluginlib</depend>
<depend>rclcpp_lifecycle</depend>
<depend>hardware_interface</depend>
<depend>franka_msgs</depend>
<depend>franka_semantic_components</depend>

<depend>moveit_core</depend>
<depend>moveit_msgs</depend>

<test_depend>ament_cmake_clang_format</test_depend>
<test_depend>ament_cmake_copyright</test_depend>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
import os
import sys
import glob
from typing import Tuple
import rclpy
from rclpy.node import Node
import numpy as np

try:
from franka_gello_state_publisher.driver import DynamixelDriver
except ImportError:
from driver import DynamixelDriver
from sensor_msgs.msg import JointState
from std_msgs.msg import Float32
import yaml
from ament_index_python.packages import get_package_share_directory
from ament_index_python.packages import get_package_share_directory, get_package_prefix


class GelloPublisher(Node):
Expand Down Expand Up @@ -72,6 +68,9 @@ def get_values_from_config(self, config_file: str):
"""Whether or not the gripper is attached."""

joint_ids = list(range(1, self.num_joints + 1))
self.add_dynamixel_driver_path()
from gello.dynamixel.driver import DynamixelDriver

self.driver = DynamixelDriver(joint_ids, port=self.com_port, baudrate=57600)
"""The driver for the Dynamixel motors."""

Expand Down Expand Up @@ -119,6 +118,12 @@ def gripper_readout_to_percent(self, gripper_position: float) -> float:
)
return max(0.0, min(1.0, gripper_percent))

def add_dynamixel_driver_path(self):
gello_path = os.path.abspath(
os.path.join(get_package_prefix("franka_gello_state_publisher"), "../../../")
)
sys.path.insert(0, gello_path)


def main(args=None):
rclpy.init(args=args)
Expand Down
8 changes: 2 additions & 6 deletions ros2/src/franka_gello_state_publisher/test/test_flake8.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,8 @@
@pytest.mark.flake8
@pytest.mark.linter
def test_flake8():
config_path = Path(__file__).resolve().parents[3] / ".flake8"
excluded_file = Path(__file__).resolve().parents[1] / "franka_gello_state_publisher/driver.py"
print(excluded_file)
rc, errors = main_with_errors(
argv=["--config", str(config_path), "--exclude", str(excluded_file)]
)
config_path = Path(__file__).resolve().parents[4] / ".flake8"
rc, errors = main_with_errors(argv=["--config", str(config_path)])
assert rc == 0, "Found %d code style errors / warnings:\n" % len(errors) + "\n".join(errors)


Expand Down
3 changes: 1 addition & 2 deletions ros2/src/franka_gripper_manager/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
<description>Provisioning of gripper clients for gello</description>
<maintainer email="support@franka.de">Franka Robotics GmbH</maintainer>
<license>Apache 2.0</license>
<depend>ros2-robotiq-gripper</depend>
<depend>sensor-msgs</depend>
<depend>sensor_msgs</depend>
<depend>rclpy</depend>

<test_depend>ament_copyright</test_depend>
Expand Down
2 changes: 1 addition & 1 deletion ros2/src/franka_gripper_manager/test/test_flake8.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@
@pytest.mark.flake8
@pytest.mark.linter
def test_flake8():
config_path = Path(__file__).resolve().parents[3] / ".flake8"
config_path = Path(__file__).resolve().parents[4] / ".flake8"
rc, errors = main_with_errors(argv=["--config", str(config_path)])
assert rc == 0, "Found %d code style errors / warnings:\n" % len(errors) + "\n".join(errors)
4 changes: 4 additions & 0 deletions scripts/gello_get_offset.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

import numpy as np
import tyro
import sys
import os

sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))

from gello.dynamixel.driver import DynamixelDriver

Expand Down
Loading