From 595fbe7745770e2b91ab1398db301372bccc8c55 Mon Sep 17 00:00:00 2001
From: thomason <84239247+thomasonzhou@users.noreply.github.com>
Date: Fri, 28 Mar 2025 18:05:38 +0900
Subject: [PATCH] Implement openarm ros2_control support with openarm_hardware
and openarm_bringup (#2)
- openarm_bringup: ros2_control bringup
- openarm_hardware: hardware interface for ros2_control
---
README.md | 11 +-
.../urdf/openarm_bimanual.urdf | 576 ------------------
openarm_bringup/CMakeLists.txt | 30 +
openarm_bringup/LICENSE | 25 +
.../config/openarm_controllers.yaml | 84 +++
.../config/test_goal_publishers_config.yaml | 58 ++
openarm_bringup/launch/openarm.launch.py | 239 ++++++++
...test_forward_position_controller.launch.py | 46 ++
...test_joint_trajectory_controller.launch.py | 46 ++
openarm_bringup/package.xml | 18 +
.../resource/openarm_description | 0
.../urdf/initial_positions.yaml | 12 +
.../urdf/openarm.ros2_control.xacro | 46 +-
openarm_description/urdf/openarm.urdf | 89 +++
openarm_description/urdf/openarm.urdf.xacro | 1 -
openarm_description/urdf/openarm.xacro | 572 ++++++++---------
openarm_hardware/CMakeLists.txt | 64 ++
openarm_hardware/LICENSE | 25 +
.../include/openarm_hardware/canbus.hpp | 26 +
.../include/openarm_hardware/motor.hpp | 94 +++
.../openarm_hardware/motor_control.hpp | 47 ++
.../openarm_hardware/openarm_hardware.hpp | 95 +++
.../openarm_hardware/visibility_control.h | 50 ++
openarm_hardware/openarm_hardware.xml | 9 +
openarm_hardware/package.xml | 18 +
openarm_hardware/setup.bash | 20 +
openarm_hardware/src/canbus.cpp | 68 +++
openarm_hardware/src/motor.cpp | 120 ++++
openarm_hardware/src/motor_control.cpp | 163 +++++
openarm_hardware/src/openarm_hardware.cpp | 138 +++++
.../test/test_openarm_hardware.cpp | 131 ++++
openarm_moveit_config/.setup_assistant | 10 +-
.../config/initial_positions.yaml | 8 +-
.../config/joint_limits.yaml | 73 +--
openarm_moveit_config/config/moveit.rviz | 8 +-
.../config/moveit_controllers.yaml | 13 +-
.../config/ompl_planning.yaml | 38 ++
openarm_moveit_config/config/openarm.srdf | 89 +++
.../config/openarm.urdf.xacro | 5 +
.../config/openarm_grip.srdf | 55 --
.../config/openarm_grip.urdf.xacro | 14 -
.../config/ros2_controllers.yaml | 19 +-
openarm_moveit_config/launch/demo.launch.py | 2 +-
.../launch/move_group.launch.py | 2 +-
.../launch/moveit_rviz.launch.py | 2 +-
openarm_moveit_config/launch/rsp.launch.py | 2 +-
.../launch/setup_assistant.launch.py | 2 +-
.../launch/spawn_controllers.launch.py | 2 +-
.../launch/static_virtual_joint_tfs.launch.py | 2 +-
.../launch/warehouse_db.launch.py | 2 +-
openarm_moveit_config/package.xml | 4 +-
51 files changed, 2248 insertions(+), 1025 deletions(-)
create mode 100644 openarm_bringup/CMakeLists.txt
create mode 100644 openarm_bringup/LICENSE
create mode 100644 openarm_bringup/config/openarm_controllers.yaml
create mode 100644 openarm_bringup/config/test_goal_publishers_config.yaml
create mode 100644 openarm_bringup/launch/openarm.launch.py
create mode 100644 openarm_bringup/launch/test_forward_position_controller.launch.py
create mode 100644 openarm_bringup/launch/test_joint_trajectory_controller.launch.py
create mode 100644 openarm_bringup/package.xml
create mode 100644 openarm_description/resource/openarm_description
create mode 100644 openarm_description/urdf/initial_positions.yaml
rename openarm_moveit_config/config/openarm_grip.ros2_control.xacro => openarm_description/urdf/openarm.ros2_control.xacro (71%)
create mode 100644 openarm_hardware/CMakeLists.txt
create mode 100644 openarm_hardware/LICENSE
create mode 100644 openarm_hardware/include/openarm_hardware/canbus.hpp
create mode 100644 openarm_hardware/include/openarm_hardware/motor.hpp
create mode 100644 openarm_hardware/include/openarm_hardware/motor_control.hpp
create mode 100644 openarm_hardware/include/openarm_hardware/openarm_hardware.hpp
create mode 100644 openarm_hardware/include/openarm_hardware/visibility_control.h
create mode 100644 openarm_hardware/openarm_hardware.xml
create mode 100644 openarm_hardware/package.xml
create mode 100755 openarm_hardware/setup.bash
create mode 100644 openarm_hardware/src/canbus.cpp
create mode 100644 openarm_hardware/src/motor.cpp
create mode 100644 openarm_hardware/src/motor_control.cpp
create mode 100644 openarm_hardware/src/openarm_hardware.cpp
create mode 100644 openarm_hardware/test/test_openarm_hardware.cpp
create mode 100644 openarm_moveit_config/config/ompl_planning.yaml
create mode 100644 openarm_moveit_config/config/openarm.srdf
create mode 100644 openarm_moveit_config/config/openarm.urdf.xacro
delete mode 100644 openarm_moveit_config/config/openarm_grip.srdf
delete mode 100644 openarm_moveit_config/config/openarm_grip.urdf.xacro
diff --git a/README.md b/README.md
index 2e2a9d9..7d53729 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,10 @@
# ROS2 packages for OpenArm robots
-- openarm_bimanual_description: urdf with pedestal torso and arm on each side
-- openarm_description: urdf with gripper actuator
+- openarm_bimanual_description: humanoid upper body with two arms (urdf)
+- openarm_description: single arm (urdf)
- openarm_moveit_config: motion planning with [moveit2](https://github.com/moveit/moveit2)
+- openarm_bringup: [ros2_control](https://control.ros.org/humble/index.html) bringup
+- openarm_hardware: hardware interface for ros2_control
## Description Packages
@@ -11,15 +13,10 @@ Each link has a visual mesh and a collision mesh, as shown in the figures below:
-### TODO:
-- [ ] Add results from true inertia tests to URDF
-
## MoveIt2 Support
https://github.com/user-attachments/assets/a0f962e5-6150-49ce-b18e-9914bcb322ef
-### TODO:
-- [ ] ROS 2 control packages (separate branch)
Tested with:
- [x] Rolling
diff --git a/openarm_bimanual_description/urdf/openarm_bimanual.urdf b/openarm_bimanual_description/urdf/openarm_bimanual.urdf
index 119b42d..e69de29 100644
--- a/openarm_bimanual_description/urdf/openarm_bimanual.urdf
+++ b/openarm_bimanual_description/urdf/openarm_bimanual.urdf
@@ -1,576 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/openarm_bringup/CMakeLists.txt b/openarm_bringup/CMakeLists.txt
new file mode 100644
index 0000000..451f441
--- /dev/null
+++ b/openarm_bringup/CMakeLists.txt
@@ -0,0 +1,30 @@
+cmake_minimum_required(VERSION 3.8)
+project(openarm_bringup)
+
+if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ add_compile_options(-Wall -Wextra -Wpedantic)
+endif()
+
+# find dependencies
+find_package(ament_cmake REQUIRED)
+# uncomment the following section in order to fill in
+# further dependencies manually.
+# find_package( REQUIRED)
+
+if(BUILD_TESTING)
+ find_package(ament_lint_auto REQUIRED)
+ # the following line skips the linter which checks for copyrights
+ # comment the line when a copyright and license is added to all source files
+ set(ament_cmake_copyright_FOUND TRUE)
+ # the following line skips cpplint (only works in a git repo)
+ # comment the line when this package is in a git repo and when
+ # a copyright and license is added to all source files
+ set(ament_cmake_cpplint_FOUND TRUE)
+ ament_lint_auto_find_test_dependencies()
+endif()
+
+install(DIRECTORY launch config
+ DESTINATION share/${PROJECT_NAME}
+)
+
+ament_package()
diff --git a/openarm_bringup/LICENSE b/openarm_bringup/LICENSE
new file mode 100644
index 0000000..574ef07
--- /dev/null
+++ b/openarm_bringup/LICENSE
@@ -0,0 +1,25 @@
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/openarm_bringup/config/openarm_controllers.yaml b/openarm_bringup/config/openarm_controllers.yaml
new file mode 100644
index 0000000..5f172e0
--- /dev/null
+++ b/openarm_bringup/config/openarm_controllers.yaml
@@ -0,0 +1,84 @@
+# Copyright (c) 2024 Stogl Robotics Consulting UG (haftungsbeschränkt)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Source of this file are templates in
+# [RosTeamWorkspace](https://github.com/StoglRobotics/ros_team_workspace) repository.
+#
+# Author: Dr. Denis
+#
+
+controller_manager:
+ ros__parameters:
+ update_rate: 100 # Hz
+
+ joint_state_broadcaster:
+ type: joint_state_broadcaster/JointStateBroadcaster
+
+ forward_position_controller:
+ type: forward_command_controller/ForwardCommandController
+
+ forward_velocity_controller:
+ type: forward_command_controller/ForwardCommandController
+
+ joint_trajectory_controller:
+ type: joint_trajectory_controller/JointTrajectoryController
+
+forward_position_controller:
+ ros__parameters:
+ joints:
+ - rev1
+ - rev2
+ - rev3
+ - rev4
+ - rev5
+ - rev6
+ - rev7
+ interface_name: position
+
+forward_velocity_controller:
+ ros__parameters:
+ joints:
+ - rev1
+ - rev2
+ - rev3
+ - rev4
+ - rev5
+ - rev6
+ - rev7
+ interface_name: velocity
+
+joint_trajectory_controller:
+ ros__parameters:
+ joints:
+ - rev1
+ - rev2
+ - rev3
+ - rev4
+ - rev5
+ - rev6
+ - rev7
+
+ command_interfaces:
+ - position
+ state_interfaces:
+ - position
+
+ state_publish_rate: 50.0 # Defaults to 50
+ action_monitor_rate: 50.0 # Defaults to 20
+
+ allow_partial_joints_goal: false # Defaults to false
+ constraints:
+ stopped_velocity_tolerance: 0.01 # Defaults to 0.01
+ goal_time: 0.0 # Defaults to 0.0 (start immediately)
diff --git a/openarm_bringup/config/test_goal_publishers_config.yaml b/openarm_bringup/config/test_goal_publishers_config.yaml
new file mode 100644
index 0000000..f750f34
--- /dev/null
+++ b/openarm_bringup/config/test_goal_publishers_config.yaml
@@ -0,0 +1,58 @@
+# Copyright (c) 2024 Stogl Robotics Consulting UG (haftungsbeschränkt)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Source of this file are templates in
+# [RosTeamWorkspace](https://github.com/StoglRobotics/ros_team_workspace) repository.
+#
+
+publisher_forward_position_controller:
+ ros__parameters:
+
+ controller_name: "forward_position_controller"
+ wait_sec_between_publish: 5
+
+ goal_names: ["pos1", "pos2", "pos3", "pos4"]
+ pos1: [0.185, 0.185, 0.185, 0.185, 0.185, 0.185, 0.185]
+ pos2: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
+ pos3: [-0.185, -0.185, -0.185, -0.185, -0.185, -0.185, -0.185]
+ pos4: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
+
+
+publisher_joint_trajectory_controller:
+ ros__parameters:
+
+ controller_name: "joint_trajectory_controller"
+ wait_sec_between_publish: 6
+ repeat_the_same_goal: 1 # useful to simulate continuous inputs
+
+ goal_time_from_start: 3.0
+ goal_names: ["pos1", "pos2", "pos3", "pos4"]
+ pos1:
+ positions: [0.185, 0.185, 0.185, 0.185, 0.185, 0.185, 0.185]
+ pos2:
+ positions: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
+ pos3:
+ positions: [-0.185, -0.185, -0.185, -0.185, -0.185, -0.185, -0.185]
+ pos4:
+ positions: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
+
+ joints:
+ - rev1
+ - rev2
+ - rev3
+ - rev4
+ - rev5
+ - rev6
+ - rev7
diff --git a/openarm_bringup/launch/openarm.launch.py b/openarm_bringup/launch/openarm.launch.py
new file mode 100644
index 0000000..039d9e6
--- /dev/null
+++ b/openarm_bringup/launch/openarm.launch.py
@@ -0,0 +1,239 @@
+# Copyright (c) 2024, Stogl Robotics Consulting UG (haftungsbeschränkt)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Source of this file are templates in
+# [RosTeamWorkspace](https://github.com/StoglRobotics/ros_team_workspace) repository.
+#
+# Author: Dr. Denis
+#
+
+from launch import LaunchDescription
+from launch.actions import DeclareLaunchArgument, RegisterEventHandler, TimerAction
+from launch.event_handlers import OnProcessExit, OnProcessStart
+from launch.substitutions import Command, FindExecutable, LaunchConfiguration, PathJoinSubstitution
+from launch_ros.actions import Node
+from launch_ros.substitutions import FindPackageShare
+
+
+def generate_launch_description():
+ # Declare arguments
+ declared_arguments = []
+ declared_arguments.append(
+ DeclareLaunchArgument(
+ "runtime_config_package",
+ default_value="openarm_bringup",
+ description='Package with the controller\'s configuration in "config" folder. \
+ Usually the argument is not set, it enables use of a custom setup.',
+ )
+ )
+ declared_arguments.append(
+ DeclareLaunchArgument(
+ "controllers_file",
+ default_value="openarm_controllers.yaml",
+ description="YAML file with the controllers configuration.",
+ )
+ )
+ declared_arguments.append(
+ DeclareLaunchArgument(
+ "description_package",
+ default_value="openarm_description",
+ description="Description package with robot URDF/xacro files. Usually the argument \
+ is not set, it enables use of a custom description.",
+ )
+ )
+ declared_arguments.append(
+ DeclareLaunchArgument(
+ "description_file",
+ default_value="openarm.urdf.xacro",
+ description="URDF/XACRO description file with the robot.",
+ )
+ )
+ declared_arguments.append(
+ DeclareLaunchArgument(
+ "prefix",
+ default_value='""',
+ description="Prefix of the joint names, useful for \
+ multi-robot setup. If changed than also joint names in the controllers' configuration \
+ have to be updated.",
+ )
+ )
+ declared_arguments.append(
+ DeclareLaunchArgument(
+ "use_mock_hardware",
+ default_value="true",
+ description="Start robot with mock hardware mirroring command to its states.",
+ )
+ )
+ declared_arguments.append(
+ DeclareLaunchArgument(
+ "mock_sensor_commands",
+ default_value="false",
+ description="Enable mock command interfaces for sensors used for simple simulations. \
+ Used only if 'use_mock_hardware' parameter is true.",
+ )
+ )
+ declared_arguments.append(
+ DeclareLaunchArgument(
+ "robot_controller",
+ default_value="joint_trajectory_controller",
+ choices=["forward_position_controller", "joint_trajectory_controller"],
+ description="Robot controller to start.",
+ )
+ )
+
+ # Initialize Arguments
+ runtime_config_package = LaunchConfiguration("runtime_config_package")
+ controllers_file = LaunchConfiguration("controllers_file")
+ description_package = LaunchConfiguration("description_package")
+ description_file = LaunchConfiguration("description_file")
+ prefix = LaunchConfiguration("prefix")
+ use_mock_hardware = LaunchConfiguration("use_mock_hardware")
+ mock_sensor_commands = LaunchConfiguration("mock_sensor_commands")
+ robot_controller = LaunchConfiguration("robot_controller")
+
+ # Get URDF via xacro
+ robot_description_content = Command(
+ [
+ PathJoinSubstitution([FindExecutable(name="xacro")]),
+ " ",
+ PathJoinSubstitution(
+ [FindPackageShare(description_package), "urdf", description_file]
+ ),
+ " ",
+ "prefix:=",
+ prefix,
+ " ",
+ "use_mock_hardware:=",
+ use_mock_hardware,
+ " ",
+ "mock_sensor_commands:=",
+ mock_sensor_commands,
+ " ",
+ ]
+ )
+
+ robot_description = {"robot_description": robot_description_content}
+
+ robot_controllers = PathJoinSubstitution(
+ [FindPackageShare(runtime_config_package), "config", controllers_file]
+ )
+ rviz_config_file = PathJoinSubstitution(
+ [FindPackageShare(description_package), "rviz", "openarm.rviz"]
+ )
+
+ control_node = Node(
+ package="controller_manager",
+ executable="ros2_control_node",
+ output="both",
+ parameters=[robot_description, robot_controllers],
+ )
+ robot_state_pub_node = Node(
+ package="robot_state_publisher",
+ executable="robot_state_publisher",
+ output="both",
+ parameters=[robot_description],
+ )
+ rviz_node = Node(
+ package="rviz2",
+ executable="rviz2",
+ name="rviz2",
+ output="log",
+ arguments=["-d", rviz_config_file],
+ )
+
+ joint_state_broadcaster_spawner = Node(
+ package="controller_manager",
+ executable="spawner",
+ arguments=["joint_state_broadcaster", "--controller-manager", "/controller_manager"],
+ )
+
+ robot_controller_names = [robot_controller]
+ robot_controller_spawners = []
+ for controller in robot_controller_names:
+ robot_controller_spawners += [
+ Node(
+ package="controller_manager",
+ executable="spawner",
+ arguments=[controller, "-c", "/controller_manager"],
+ )
+ ]
+
+ inactive_robot_controller_names = []
+ inactive_robot_controller_spawners = []
+ for controller in inactive_robot_controller_names:
+ inactive_robot_controller_spawners += [
+ Node(
+ package="controller_manager",
+ executable="spawner",
+ arguments=[controller, "-c", "/controller_manager", "--inactive"],
+ )
+ ]
+
+ # Delay loading and activation of `joint_state_broadcaster` after start of ros2_control_node
+ delay_joint_state_broadcaster_spawner_after_ros2_control_node = RegisterEventHandler(
+ event_handler=OnProcessStart(
+ target_action=control_node,
+ on_start=[
+ TimerAction(
+ period=3.0,
+ actions=[joint_state_broadcaster_spawner],
+ ),
+ ],
+ )
+ )
+
+ # Delay loading and activation of robot_controller_names after `joint_state_broadcaster`
+ delay_robot_controller_spawners_after_joint_state_broadcaster_spawner = []
+ for i, controller in enumerate(robot_controller_spawners):
+ delay_robot_controller_spawners_after_joint_state_broadcaster_spawner += [
+ RegisterEventHandler(
+ event_handler=OnProcessExit(
+ target_action=(
+ robot_controller_spawners[i - 1]
+ if i > 0
+ else joint_state_broadcaster_spawner
+ ),
+ on_exit=[controller],
+ )
+ )
+ ]
+
+ # Delay start of inactive_robot_controller_names after other controllers
+ delay_inactive_robot_controller_spawners_after_joint_state_broadcaster_spawner = []
+ for i, controller in enumerate(inactive_robot_controller_spawners):
+ delay_inactive_robot_controller_spawners_after_joint_state_broadcaster_spawner += [
+ RegisterEventHandler(
+ event_handler=OnProcessExit(
+ target_action=(
+ inactive_robot_controller_spawners[i - 1]
+ if i > 0
+ else robot_controller_spawners[-1]
+ ),
+ on_exit=[controller],
+ )
+ )
+ ]
+
+ return LaunchDescription(
+ declared_arguments
+ + [
+ control_node,
+ robot_state_pub_node,
+ rviz_node,
+ delay_joint_state_broadcaster_spawner_after_ros2_control_node,
+ ]
+ + delay_robot_controller_spawners_after_joint_state_broadcaster_spawner
+ + delay_inactive_robot_controller_spawners_after_joint_state_broadcaster_spawner
+ )
diff --git a/openarm_bringup/launch/test_forward_position_controller.launch.py b/openarm_bringup/launch/test_forward_position_controller.launch.py
new file mode 100644
index 0000000..e6a4b3a
--- /dev/null
+++ b/openarm_bringup/launch/test_forward_position_controller.launch.py
@@ -0,0 +1,46 @@
+# Copyright (c) 2024, Stogl Robotics Consulting UG (haftungsbeschränkt)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Source of this file are templates in
+# [RosTeamWorkspace](https://github.com/StoglRobotics/ros_team_workspace) repository.
+#
+# Author: Dr. Denis
+#
+
+from launch import LaunchDescription
+from launch.substitutions import PathJoinSubstitution
+from launch_ros.actions import Node
+from launch_ros.substitutions import FindPackageShare
+
+
+def generate_launch_description():
+ position_goals = PathJoinSubstitution(
+ [FindPackageShare("openarm_bringup"), "config", "test_goal_publishers_config.yaml"]
+ )
+
+ return LaunchDescription(
+ [
+ Node(
+ package="ros2_controllers_test_nodes",
+ executable="publisher_forward_position_controller",
+ name="publisher_forward_position_controller",
+ parameters=[position_goals],
+ output={
+ "stdout": "screen",
+ "stderr": "screen",
+ },
+ )
+ ]
+ )
diff --git a/openarm_bringup/launch/test_joint_trajectory_controller.launch.py b/openarm_bringup/launch/test_joint_trajectory_controller.launch.py
new file mode 100644
index 0000000..f882dfe
--- /dev/null
+++ b/openarm_bringup/launch/test_joint_trajectory_controller.launch.py
@@ -0,0 +1,46 @@
+# Copyright (c) 2024, Stogl Robotics Consulting UG (haftungsbeschränkt)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Source of this file are templates in
+# [RosTeamWorkspace](https://github.com/StoglRobotics/ros_team_workspace) repository.
+#
+# Author: Dr. Denis
+#
+
+from launch import LaunchDescription
+from launch.substitutions import PathJoinSubstitution
+from launch_ros.actions import Node
+from launch_ros.substitutions import FindPackageShare
+
+
+def generate_launch_description():
+ position_goals = PathJoinSubstitution(
+ [FindPackageShare("openarm_bringup"), "config", "test_goal_publishers_config.yaml"]
+ )
+
+ return LaunchDescription(
+ [
+ Node(
+ package="ros2_controllers_test_nodes",
+ executable="publisher_joint_trajectory_controller",
+ name="publisher_joint_trajectory_controller",
+ parameters=[position_goals],
+ output={
+ "stdout": "screen",
+ "stderr": "screen",
+ },
+ )
+ ]
+ )
diff --git a/openarm_bringup/package.xml b/openarm_bringup/package.xml
new file mode 100644
index 0000000..9ef5f5b
--- /dev/null
+++ b/openarm_bringup/package.xml
@@ -0,0 +1,18 @@
+
+
+
+ openarm_bringup
+ 0.0.0
+ Bringup script for OpenArm
+ Thomason Zhou
+ BSD-3-Clause
+
+ ament_cmake
+
+ ament_lint_auto
+ ament_lint_common
+
+
+ ament_cmake
+
+
diff --git a/openarm_description/resource/openarm_description b/openarm_description/resource/openarm_description
new file mode 100644
index 0000000..e69de29
diff --git a/openarm_description/urdf/initial_positions.yaml b/openarm_description/urdf/initial_positions.yaml
new file mode 100644
index 0000000..b636de3
--- /dev/null
+++ b/openarm_description/urdf/initial_positions.yaml
@@ -0,0 +1,12 @@
+# Default initial positions for openarm's ros2_control fake system
+
+initial_positions:
+ left_pris1: 0
+ right_pris2: 0
+ rev1: 0
+ rev2: 0
+ rev3: 0
+ rev4: 0
+ rev5: 0
+ rev6: 0
+ rev7: 0
diff --git a/openarm_moveit_config/config/openarm_grip.ros2_control.xacro b/openarm_description/urdf/openarm.ros2_control.xacro
similarity index 71%
rename from openarm_moveit_config/config/openarm_grip.ros2_control.xacro
rename to openarm_description/urdf/openarm.ros2_control.xacro
index c5d7e6e..c269488 100644
--- a/openarm_moveit_config/config/openarm_grip.ros2_control.xacro
+++ b/openarm_description/urdf/openarm.ros2_control.xacro
@@ -1,84 +1,96 @@
-
+
-
+
mock_components/GenericSystem
+ openarm_hardware/OpenArmHW
-
+
+
${initial_positions['rev1']}
+
-
+
+
${initial_positions['rev2']}
+
-
+
+
${initial_positions['rev3']}
+
-
+
+
${initial_positions['rev4']}
+
-
+
+
${initial_positions['rev5']}
+
-
+
+
${initial_positions['rev6']}
+
-
+
+
${initial_positions['rev7']}
+
-
+
-
- ${initial_positions['slider_left']}
+ ${initial_positions['left_pris1']}
-
-
-
+
+
- ${initial_positions['slider_right']}
+ ${initial_positions['left_pris1']}
-
diff --git a/openarm_description/urdf/openarm.urdf b/openarm_description/urdf/openarm.urdf
index 4d767af..06a7b76 100644
--- a/openarm_description/urdf/openarm.urdf
+++ b/openarm_description/urdf/openarm.urdf
@@ -10,6 +10,95 @@
+
+
+
+ mock_components/GenericSystem
+ openarm_hardware/OpenArmHW
+
+
+
+
+
+
+ 0
+
+
+
+
+
+
+
+
+
+ 0
+
+
+
+
+
+
+
+
+
+ 0
+
+
+
+
+
+
+
+
+
+ 0
+
+
+
+
+
+
+
+
+
+ 0
+
+
+
+
+
+
+
+
+
+ 0
+
+
+
+
+
+
+
+
+
+ 0
+
+
+
+
+
+
+
+ 0
+
+
+
+
+
+ 0
+
+
+
diff --git a/openarm_description/urdf/openarm.urdf.xacro b/openarm_description/urdf/openarm.urdf.xacro
index 65a59f3..0fbad44 100644
--- a/openarm_description/urdf/openarm.urdf.xacro
+++ b/openarm_description/urdf/openarm.urdf.xacro
@@ -2,5 +2,4 @@
-
diff --git a/openarm_description/urdf/openarm.xacro b/openarm_description/urdf/openarm.xacro
index 33427ea..033f81d 100644
--- a/openarm_description/urdf/openarm.xacro
+++ b/openarm_description/urdf/openarm.xacro
@@ -1,282 +1,290 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/openarm_hardware/CMakeLists.txt b/openarm_hardware/CMakeLists.txt
new file mode 100644
index 0000000..0997c50
--- /dev/null
+++ b/openarm_hardware/CMakeLists.txt
@@ -0,0 +1,64 @@
+cmake_minimum_required(VERSION 3.8)
+project(openarm_hardware)
+
+if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ add_compile_options(-Wall -Wextra -Wpedantic)
+endif()
+
+# find dependencies
+find_package(ament_cmake REQUIRED)
+# uncomment the following section in order to fill in
+# further dependencies manually.
+find_package(hardware_interface REQUIRED)
+find_package(pluginlib REQUIRED)
+find_package(rclcpp REQUIRED)
+find_package(rclcpp_lifecycle REQUIRED)
+
+add_library(${PROJECT_NAME} SHARED
+ src/openarm_hardware.cpp
+)
+
+target_include_directories(${PROJECT_NAME}
+ PUBLIC
+ $
+ $
+)
+
+ament_target_dependencies(${PROJECT_NAME}
+ hardware_interface
+ pluginlib
+ rclcpp
+ rclcpp_lifecycle
+)
+ament_export_libraries(${PROJECT_NAME})
+pluginlib_export_plugin_description_file(hardware_interface openarm_hardware.xml)
+
+install(DIRECTORY include/
+ DESTINATION include
+)
+
+install(FILES
+ openarm_hardware.xml
+ DESTINATION share/${PROJECT_NAME}
+)
+
+if(BUILD_TESTING)
+ find_package(ament_lint_auto REQUIRED)
+ find_package(ament_cmake_gmock REQUIRED)
+
+ ament_add_gmock(test_openarm_hardware
+ test/test_openarm_hardware.cpp
+ )
+ target_link_libraries(test_openarm_hardware
+ ${PROJECT_NAME}
+ )
+ ament_target_dependencies(test_openarm_hardware
+ hardware_interface
+ )
+
+ set(ament_cmake_copyright_FOUND TRUE)
+ set(ament_cmake_cpplint_FOUND TRUE)
+ ament_lint_auto_find_test_dependencies()
+endif()
+
+ament_package()
diff --git a/openarm_hardware/LICENSE b/openarm_hardware/LICENSE
new file mode 100644
index 0000000..574ef07
--- /dev/null
+++ b/openarm_hardware/LICENSE
@@ -0,0 +1,25 @@
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/openarm_hardware/include/openarm_hardware/canbus.hpp b/openarm_hardware/include/openarm_hardware/canbus.hpp
new file mode 100644
index 0000000..0fe6be1
--- /dev/null
+++ b/openarm_hardware/include/openarm_hardware/canbus.hpp
@@ -0,0 +1,26 @@
+#ifndef CANBUS_H
+#define CANBUS_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+class CANBus {
+public:
+ explicit CANBus(const std::string& interface);
+ ~CANBus();
+
+ bool send(uint16_t motor_id, const std::array& data);
+ struct can_frame recv();
+
+private:
+ int sock_;
+};
+
+#endif // CANBUS_H
diff --git a/openarm_hardware/include/openarm_hardware/motor.hpp b/openarm_hardware/include/openarm_hardware/motor.hpp
new file mode 100644
index 0000000..83e7c84
--- /dev/null
+++ b/openarm_hardware/include/openarm_hardware/motor.hpp
@@ -0,0 +1,94 @@
+#ifndef MOTOR_H
+#define MOTOR_H
+
+#include
+#include