mirror of
https://github.com/SHC-ASTRA/rover-ros2.git
synced 2026-02-11 09:20:40 +00:00
feat: add arm_hardware_controller to act as a hardware interface for IK
This commit is contained in:
120
src/arm_hardware_controller/CMakeLists.txt
Normal file
120
src/arm_hardware_controller/CMakeLists.txt
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
project(arm_hardware_controller LANGUAGES CXX)
|
||||||
|
|
||||||
|
find_package(ros2_control_cmake REQUIRED)
|
||||||
|
set_compiler_options()
|
||||||
|
export_windows_symbols()
|
||||||
|
|
||||||
|
# find dependencies
|
||||||
|
set(HW_IF_INCLUDE_DEPENDS
|
||||||
|
pluginlib
|
||||||
|
hardware_interface
|
||||||
|
ros2_interfaces_pkg
|
||||||
|
)
|
||||||
|
set(REF_GEN_INCLUDE_DEPENDS
|
||||||
|
kdl_parser
|
||||||
|
rclcpp
|
||||||
|
trajectory_msgs
|
||||||
|
)
|
||||||
|
set(CONTROLLER_INCLUDE_DEPENDS
|
||||||
|
pluginlib
|
||||||
|
controller_interface
|
||||||
|
realtime_tools
|
||||||
|
trajectory_msgs
|
||||||
|
)
|
||||||
|
|
||||||
|
# Specify the required version of ros2_control
|
||||||
|
find_package(controller_manager 4.0.0)
|
||||||
|
# Handle the case where the required version is not found
|
||||||
|
if(NOT controller_manager_FOUND)
|
||||||
|
message(FATAL_ERROR "ros2_control version 4.0.0 or higher is required. "
|
||||||
|
"Are you using the correct branch of the ros2_control_demos repository?")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# find dependencies
|
||||||
|
find_package(backward_ros REQUIRED)
|
||||||
|
find_package(ament_cmake REQUIRED)
|
||||||
|
foreach(Dependency IN ITEMS ${HW_IF_INCLUDE_DEPENDS})
|
||||||
|
find_package(${Dependency} REQUIRED)
|
||||||
|
endforeach()
|
||||||
|
foreach(Dependency IN ITEMS ${REF_GEN_INCLUDE_DEPENDS})
|
||||||
|
find_package(${Dependency} REQUIRED)
|
||||||
|
endforeach()
|
||||||
|
foreach(Dependency IN ITEMS ${CONTROLLER_INCLUDE_DEPENDS})
|
||||||
|
find_package(${Dependency} REQUIRED)
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
|
||||||
|
## COMPILE
|
||||||
|
# add_executable(send_trajectory reference_generator/send_trajectory.cpp)
|
||||||
|
|
||||||
|
# target_link_libraries(send_trajectory PUBLIC
|
||||||
|
# ${trajectory_msgs_TARGETS}
|
||||||
|
# kdl_parser::kdl_parser
|
||||||
|
# rclcpp::rclcpp
|
||||||
|
# )
|
||||||
|
|
||||||
|
add_library(
|
||||||
|
arm_hardware_controller
|
||||||
|
SHARED
|
||||||
|
hardware/arm_controller.cpp
|
||||||
|
# controller/r6bot_controller.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
target_compile_features(arm_hardware_controller PUBLIC cxx_std_17)
|
||||||
|
target_include_directories(arm_hardware_controller PUBLIC
|
||||||
|
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/hardware/include>
|
||||||
|
# $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/controller/include>
|
||||||
|
$<INSTALL_INTERFACE:include/arm_hardware_controller>
|
||||||
|
${ros2_interfaces_pkg_INCLUDE_DIRS} # fixes "no such file or directory" compilation error for "ros2_interfaces_pkg/msg/arm_ik.hpp"
|
||||||
|
)
|
||||||
|
target_link_libraries(arm_hardware_controller PUBLIC
|
||||||
|
${trajectory_msgs_TARGETS}
|
||||||
|
# controller_interface::controller_interface
|
||||||
|
hardware_interface::hardware_interface
|
||||||
|
pluginlib::pluginlib
|
||||||
|
realtime_tools::realtime_tools
|
||||||
|
)
|
||||||
|
|
||||||
|
# Export hardware plugins
|
||||||
|
pluginlib_export_plugin_description_file(hardware_interface arm_hardware_controller.xml)
|
||||||
|
# Export controller plugins
|
||||||
|
# pluginlib_export_plugin_description_file(controller_interface arm_hardware_controller.xml)
|
||||||
|
|
||||||
|
# INSTALL
|
||||||
|
install(
|
||||||
|
DIRECTORY hardware/include/
|
||||||
|
DESTINATION include #/arm_hardware_controller
|
||||||
|
)
|
||||||
|
# install(
|
||||||
|
# DIRECTORY description/launch description/ros2_control description/urdf
|
||||||
|
# DESTINATION share/arm_hardware_controller
|
||||||
|
# )
|
||||||
|
# install(
|
||||||
|
# DIRECTORY bringup/launch bringup/config
|
||||||
|
# DESTINATION share/arm_hardware_controller
|
||||||
|
# )
|
||||||
|
# install(
|
||||||
|
# TARGETS send_trajectory
|
||||||
|
# RUNTIME DESTINATION lib/arm_hardware_controller
|
||||||
|
# )
|
||||||
|
|
||||||
|
install(TARGETS arm_hardware_controller
|
||||||
|
EXPORT export_arm_hardware_controller
|
||||||
|
ARCHIVE DESTINATION lib
|
||||||
|
LIBRARY DESTINATION lib
|
||||||
|
RUNTIME DESTINATION bin
|
||||||
|
)
|
||||||
|
|
||||||
|
# if(BUILD_TESTING)
|
||||||
|
# find_package(ament_cmake_pytest REQUIRED)
|
||||||
|
|
||||||
|
# ament_add_pytest_test(example_7_urdf_xacro test/test_urdf_xacro.py)
|
||||||
|
# ament_add_pytest_test(view_example_7_launch test/test_view_robot_launch.py)
|
||||||
|
# ament_add_pytest_test(run_example_7_launch test/test_r6bot_controller_launch.py)
|
||||||
|
# endif()
|
||||||
|
|
||||||
|
## EXPORTS
|
||||||
|
ament_export_targets(export_arm_hardware_controller HAS_LIBRARY_TARGET)
|
||||||
|
ament_export_dependencies(${HW_IF_INCLUDE_DEPENDS} ${REF_GEN_INCLUDE_DEPENDS} ${CONTROLLER_INCLUDE_DEPENDS})
|
||||||
|
ament_package()
|
||||||
16
src/arm_hardware_controller/arm_hardware_controller.xml
Normal file
16
src/arm_hardware_controller/arm_hardware_controller.xml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<library path="arm_hardware_controller">
|
||||||
|
<class name="arm_hardware_controller/ArmSystem"
|
||||||
|
type="arm_hardware_controller::ArmSystem"
|
||||||
|
base_class_type="hardware_interface::SystemInterface">
|
||||||
|
<description>
|
||||||
|
Robot hardware plugin for 6 dof robot tutorial.
|
||||||
|
</description>
|
||||||
|
</class>
|
||||||
|
<!-- <class name="arm_hardware_controller/ArmController"
|
||||||
|
type="arm_hardware_controller::ArmController"
|
||||||
|
base_class_type="controller_interface::ControllerInterface">
|
||||||
|
<description>
|
||||||
|
Robot controller plugin for 6 dof robot tutorial.
|
||||||
|
</description>
|
||||||
|
</class> -->
|
||||||
|
</library>
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
# Copyright 2023 ros2_control Development Team
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
from launch import LaunchDescription
|
||||||
|
from launch.actions import RegisterEventHandler, DeclareLaunchArgument
|
||||||
|
from launch.conditions import IfCondition
|
||||||
|
from launch.event_handlers import OnProcessExit
|
||||||
|
from launch.substitutions import Command, FindExecutable, PathJoinSubstitution, LaunchConfiguration
|
||||||
|
|
||||||
|
from launch_ros.actions import Node
|
||||||
|
from launch_ros.substitutions import FindPackageShare
|
||||||
|
|
||||||
|
|
||||||
|
def generate_launch_description():
|
||||||
|
# Declare arguments
|
||||||
|
declared_arguments = []
|
||||||
|
declared_arguments.append(
|
||||||
|
DeclareLaunchArgument(
|
||||||
|
"gui",
|
||||||
|
default_value="true",
|
||||||
|
description="Start RViz2 automatically with this launch file.",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
# Get URDF via xacro
|
||||||
|
robot_description_content = Command(
|
||||||
|
[
|
||||||
|
PathJoinSubstitution([FindExecutable(name="xacro")]),
|
||||||
|
" ",
|
||||||
|
PathJoinSubstitution(
|
||||||
|
[
|
||||||
|
FindPackageShare("ros2_control_demo_example_7"),
|
||||||
|
"urdf",
|
||||||
|
"r6bot.urdf.xacro",
|
||||||
|
]
|
||||||
|
),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
robot_description = {"robot_description": robot_description_content}
|
||||||
|
|
||||||
|
robot_controllers = PathJoinSubstitution(
|
||||||
|
[
|
||||||
|
FindPackageShare("ros2_control_demo_example_7"),
|
||||||
|
"config",
|
||||||
|
"r6bot_controller.yaml",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
rviz_config_file = PathJoinSubstitution(
|
||||||
|
[FindPackageShare("ros2_control_demo_description"), "r6bot/rviz", "view_robot.rviz"]
|
||||||
|
)
|
||||||
|
|
||||||
|
control_node = Node(
|
||||||
|
package="controller_manager",
|
||||||
|
executable="ros2_control_node",
|
||||||
|
parameters=[robot_controllers],
|
||||||
|
output="both",
|
||||||
|
)
|
||||||
|
robot_state_pub_node = Node(
|
||||||
|
package="robot_state_publisher",
|
||||||
|
executable="robot_state_publisher",
|
||||||
|
output="both",
|
||||||
|
parameters=[robot_description],
|
||||||
|
)
|
||||||
|
|
||||||
|
gui = LaunchConfiguration("gui")
|
||||||
|
rviz_node = Node(
|
||||||
|
package="rviz2",
|
||||||
|
executable="rviz2",
|
||||||
|
name="rviz2",
|
||||||
|
output="log",
|
||||||
|
arguments=["-d", rviz_config_file],
|
||||||
|
condition=IfCondition(gui),
|
||||||
|
)
|
||||||
|
|
||||||
|
joint_state_broadcaster_spawner = Node(
|
||||||
|
package="controller_manager",
|
||||||
|
executable="spawner",
|
||||||
|
arguments=["joint_state_broadcaster"],
|
||||||
|
)
|
||||||
|
|
||||||
|
robot_controller_spawner = Node(
|
||||||
|
package="controller_manager",
|
||||||
|
executable="spawner",
|
||||||
|
arguments=["r6bot_controller", "--param-file", robot_controllers],
|
||||||
|
)
|
||||||
|
|
||||||
|
# Delay rviz start after `joint_state_broadcaster`
|
||||||
|
delay_rviz_after_joint_state_broadcaster_spawner = RegisterEventHandler(
|
||||||
|
event_handler=OnProcessExit(
|
||||||
|
target_action=joint_state_broadcaster_spawner,
|
||||||
|
on_exit=[rviz_node],
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Delay start of joint_state_broadcaster after `robot_controller`
|
||||||
|
# TODO(anyone): This is a workaround for flaky tests. Remove when fixed.
|
||||||
|
delay_joint_state_broadcaster_after_robot_controller_spawner = RegisterEventHandler(
|
||||||
|
event_handler=OnProcessExit(
|
||||||
|
target_action=robot_controller_spawner,
|
||||||
|
on_exit=[joint_state_broadcaster_spawner],
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
nodes = [
|
||||||
|
control_node,
|
||||||
|
robot_state_pub_node,
|
||||||
|
robot_controller_spawner,
|
||||||
|
delay_rviz_after_joint_state_broadcaster_spawner,
|
||||||
|
delay_joint_state_broadcaster_after_robot_controller_spawner,
|
||||||
|
]
|
||||||
|
|
||||||
|
return LaunchDescription(declared_arguments + nodes)
|
||||||
91
src/arm_hardware_controller/hardware/arm_controller.cpp
Normal file
91
src/arm_hardware_controller/hardware/arm_controller.cpp
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
// Copyright 2023 ros2_control Development Team
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
#include "arm_hardware_controller/arm_controller.hpp"
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace astra_arm
|
||||||
|
{
|
||||||
|
|
||||||
|
CallbackReturn ArmSystem::on_init(const hardware_interface::HardwareInfo & info)
|
||||||
|
{
|
||||||
|
if (hardware_interface::SystemInterface::on_init(info) != CallbackReturn::SUCCESS)
|
||||||
|
{
|
||||||
|
return CallbackReturn::ERROR;
|
||||||
|
}
|
||||||
|
return hardware_interface::CallbackReturn::SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
CallbackReturn ArmSystem::on_configure(const rclcpp_lifecycle::State & /*previous_state*/)
|
||||||
|
{
|
||||||
|
// reset values always when configuring hardware
|
||||||
|
for (const auto & [name, descr] : joint_state_interfaces_)
|
||||||
|
{
|
||||||
|
set_state(name, 0.0);
|
||||||
|
}
|
||||||
|
for (const auto & [name, descr] : joint_command_interfaces_)
|
||||||
|
{
|
||||||
|
set_command(name, 0.0);
|
||||||
|
}
|
||||||
|
for (const auto & [name, descr] : sensor_state_interfaces_)
|
||||||
|
{
|
||||||
|
set_state(name, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return CallbackReturn::SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return_type ArmSystem::read(const rclcpp::Time & /*time*/, const rclcpp::Duration & period)
|
||||||
|
{
|
||||||
|
// TODO(pac48) set sensor_states_ values from subscriber
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < info_.joints.size(); i++)
|
||||||
|
{
|
||||||
|
const auto name_vel = info_.joints[i].name + "/" + hardware_interface::HW_IF_VELOCITY;
|
||||||
|
const auto name_pos = info_.joints[i].name + "/" + hardware_interface::HW_IF_POSITION;
|
||||||
|
set_state(name_vel, get_command(name_vel));
|
||||||
|
set_state(name_pos, get_state(name_pos) + get_state(name_vel) * period.seconds());
|
||||||
|
}
|
||||||
|
return return_type::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return_type ArmSystem::write(const rclcpp::Time &, const rclcpp::Duration &)
|
||||||
|
{
|
||||||
|
return return_type::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ArmSystem::state_sub_callback(
|
||||||
|
const sensor_msgs::msg::JointState::SharedPtr msg)
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < msg->name.size(); i++)
|
||||||
|
{
|
||||||
|
if (joint_state_interfaces_.find(msg->name[i]) != joint_state_interfaces_.end())
|
||||||
|
{
|
||||||
|
set_state(msg->name[i] + "/" + hardware_interface::HW_IF_POSITION, msg->position[i]);
|
||||||
|
if (!msg->position.empty())
|
||||||
|
set_state(msg->name[i] + "/" + hardware_interface::HW_IF_VELOCITY, msg->velocity[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
last_state_time_ = std::chrono::steady_clock::now();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace astra_arm
|
||||||
|
|
||||||
|
#include "pluginlib/class_list_macros.hpp"
|
||||||
|
|
||||||
|
PLUGINLIB_EXPORT_CLASS(
|
||||||
|
astra_arm::ArmSystem, hardware_interface::SystemInterface)
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
// Copyright 2023 ros2_control Development Team
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
#ifndef ASTRA_ARM__HARDWARE_HPP_
|
||||||
|
#define ASTRA_ARM__HARDWARE_HPP_
|
||||||
|
|
||||||
|
#include "string"
|
||||||
|
#include "unordered_map"
|
||||||
|
#include "vector"
|
||||||
|
|
||||||
|
#include "hardware_interface/handle.hpp"
|
||||||
|
#include "hardware_interface/hardware_info.hpp"
|
||||||
|
#include "hardware_interface/system_interface.hpp"
|
||||||
|
#include "hardware_interface/types/hardware_interface_return_values.hpp"
|
||||||
|
#include "hardware_interface/types/hardware_interface_type_values.hpp"
|
||||||
|
|
||||||
|
#include "ros2_interfaces_pkg/msg/arm_ik.hpp"
|
||||||
|
#include "sensor_msgs/msg/joint_state.hpp"
|
||||||
|
|
||||||
|
using hardware_interface::return_type;
|
||||||
|
|
||||||
|
namespace astra_arm
|
||||||
|
{
|
||||||
|
using CallbackReturn = rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn;
|
||||||
|
|
||||||
|
class ArmSystem : public hardware_interface::SystemInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Boilerplate
|
||||||
|
CallbackReturn on_init(const hardware_interface::HardwareInfo & info) override;
|
||||||
|
CallbackReturn on_configure(const rclcpp_lifecycle::State & previous_state) override;
|
||||||
|
return_type read(const rclcpp::Time & time, const rclcpp::Duration & period) override;
|
||||||
|
return_type write(const rclcpp::Time & /*time*/, const rclcpp::Duration & /*period*/) override;
|
||||||
|
private:
|
||||||
|
// Comms with arm_pkg
|
||||||
|
rclcpp::Publisher<ros2_interfaces_pkg::msg::ArmIK>::SharedPtr command_pub_;
|
||||||
|
void state_sub_callback(const sensor_msgs::msg::JointState::SharedPtr msg);
|
||||||
|
rclcpp::Subscription<sensor_msgs::msg::JointState>::SharedPtr state_sub_;
|
||||||
|
|
||||||
|
std::vector<double> cmd_;
|
||||||
|
std::vector<double> pos_, vel_;
|
||||||
|
std::chrono::steady_clock::time_point last_state_time_;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace astra_arm
|
||||||
|
|
||||||
|
#endif // ASTRA_ARM__HARDWARE_HPP_
|
||||||
54
src/arm_hardware_controller/package.xml
Normal file
54
src/arm_hardware_controller/package.xml
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
|
||||||
|
<package format="3">
|
||||||
|
<name>arm_hardware_controller</name>
|
||||||
|
<version>0.0.0</version>
|
||||||
|
<description>Demo for 6 DOF robot.</description>
|
||||||
|
|
||||||
|
<maintainer email="denis.stogl@stoglrobotics.de">Dr.-Ing. Denis Štogl</maintainer>
|
||||||
|
<maintainer email="bence.magyar.robotics@gmail.com">Bence Magyar</maintainer>
|
||||||
|
<maintainer email="christoph.froehlich@ait.ac.at">Christoph Froehlich</maintainer>
|
||||||
|
<maintainer email="sai.kishor@pal-robotics.com">Sai Kishor Kothakota</maintainer>
|
||||||
|
|
||||||
|
<license>Apache-2.0</license>
|
||||||
|
|
||||||
|
<author email="paul.gesel@picknik.ai">Paul Gesel</author>
|
||||||
|
|
||||||
|
<buildtool_depend>ament_cmake</buildtool_depend>
|
||||||
|
<build_depend>ros2_control_cmake</build_depend>
|
||||||
|
<build_depend>ros2_interfaces_pkg</build_depend>
|
||||||
|
|
||||||
|
<depend>backward_ros</depend>
|
||||||
|
<depend>control_msgs</depend>
|
||||||
|
<depend>controller_interface</depend>
|
||||||
|
<depend>hardware_interface</depend>
|
||||||
|
<depend>kdl_parser</depend>
|
||||||
|
<depend>pluginlib</depend>
|
||||||
|
<depend>rclcpp_lifecycle</depend>
|
||||||
|
<depend>rclcpp</depend>
|
||||||
|
<depend>realtime_tools</depend>
|
||||||
|
<depend>trajectory_msgs</depend>
|
||||||
|
|
||||||
|
<exec_depend>controller_manager</exec_depend>
|
||||||
|
<exec_depend>joint_state_broadcaster</exec_depend>
|
||||||
|
<exec_depend>joint_state_publisher_gui</exec_depend>
|
||||||
|
<exec_depend>launch_ros</exec_depend>
|
||||||
|
<exec_depend>launch</exec_depend>
|
||||||
|
<exec_depend>robot_state_publisher</exec_depend>
|
||||||
|
<exec_depend>ros2_control_demo_description</exec_depend>
|
||||||
|
<exec_depend>ros2controlcli</exec_depend>
|
||||||
|
<exec_depend>ros2launch</exec_depend>
|
||||||
|
<exec_depend>rviz2</exec_depend>
|
||||||
|
<exec_depend>urdf</exec_depend>
|
||||||
|
<exec_depend>xacro</exec_depend>
|
||||||
|
|
||||||
|
<test_depend>ament_cmake_pytest</test_depend>
|
||||||
|
<test_depend>launch_testing</test_depend>
|
||||||
|
<test_depend>launch</test_depend>
|
||||||
|
<test_depend>liburdfdom-tools</test_depend>
|
||||||
|
<test_depend>rclpy</test_depend>
|
||||||
|
|
||||||
|
<export>
|
||||||
|
<build_type>ament_cmake</build_type>
|
||||||
|
</export>
|
||||||
|
</package>
|
||||||
Reference in New Issue
Block a user