Skip to content

Commit aa004a3

Browse files
committed
Added joint limiter plugins.
- Added initial structures for joint-limit plugins. - Correct ruckig name and make tests to work. - Rename the joint_limits package - Comment and author cleanup - Base class does not require libary. - Delete extra layer of abstraction since not all plugins require a vector of smoothing objects. - Restore simple_joint_limiter to a working state - Implement init() and enforce() - Return of joint_limits package. - Move Ruckig limiter to package joint_limits_enforcement_plugins and make it working.
1 parent 5d81a98 commit aa004a3

File tree

16 files changed

+913
-4
lines changed

16 files changed

+913
-4
lines changed

joint_limits/CMakeLists.txt

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang)")
66
endif()
77

88
set(THIS_PACKAGE_INCLUDE_DEPENDS
9+
pluginlib
910
rclcpp
1011
rclcpp_lifecycle
12+
trajectory_msgs
1113
)
1214

1315
find_package(ament_cmake REQUIRED)
@@ -23,10 +25,41 @@ target_include_directories(joint_limits INTERFACE
2325
)
2426
ament_target_dependencies(joint_limits INTERFACE ${THIS_PACKAGE_INCLUDE_DEPENDS})
2527

28+
add_library(joint_limiter_interface SHARED
29+
src/joint_limiter_interface.cpp
30+
)
31+
target_compile_features(joint_limiter_interface PUBLIC cxx_std_17)
32+
target_include_directories(joint_limiter_interface PUBLIC
33+
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
34+
$<INSTALL_INTERFACE:include/joint_limits>
35+
)
36+
ament_target_dependencies(joint_limiter_interface PUBLIC ${THIS_PACKAGE_INCLUDE_DEPENDS})
37+
# Causes the visibility macros to use dllexport rather than dllimport,
38+
# which is appropriate when building the dll but not consuming it.
39+
target_compile_definitions(joint_limiter_interface PRIVATE "JOINT_LIMITS_BUILDING_DLL")
40+
41+
42+
add_library(simple_joint_limiter SHARED
43+
src/simple_joint_limiter.cpp
44+
)
45+
target_compile_features(simple_joint_limiter PUBLIC cxx_std_17)
46+
target_include_directories(simple_joint_limiter PUBLIC
47+
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
48+
$<INSTALL_INTERFACE:include/joint_limits>
49+
)
50+
ament_target_dependencies(simple_joint_limiter PUBLIC ${THIS_PACKAGE_INCLUDE_DEPENDS})
51+
# Causes the visibility macros to use dllexport rather than dllimport,
52+
# which is appropriate when building the dll but not consuming it.
53+
target_compile_definitions(simple_joint_limiter PRIVATE "JOINT_LIMITS_BUILDING_DLL")
54+
55+
pluginlib_export_plugin_description_file(joint_limits joint_limiters.xml)
2656

2757
if(BUILD_TESTING)
2858
find_package(ament_cmake_gtest REQUIRED)
59+
find_package(ament_cmake_gmock REQUIRED)
2960
find_package(launch_testing_ament_cmake REQUIRED)
61+
find_package(pluginlib REQUIRED)
62+
find_package(rclcpp REQUIRED)
3063

3164
ament_add_gtest_executable(joint_limits_rosparam_test test/joint_limits_rosparam_test.cpp)
3265
target_link_libraries(joint_limits_rosparam_test joint_limits)
@@ -40,13 +73,25 @@ if(BUILD_TESTING)
4073
FILES test/joint_limits_rosparam.yaml
4174
DESTINATION share/joint_limits/test
4275
)
76+
77+
ament_add_gmock(test_simple_joint_limiter test/test_simple_joint_limiter.cpp)
78+
target_include_directories(test_simple_joint_limiter PRIVATE include)
79+
target_link_libraries(test_simple_joint_limiter joint_limiter_interface)
80+
ament_target_dependencies(
81+
test_simple_joint_limiter
82+
pluginlib
83+
rclcpp
84+
)
4385
endif()
4486

4587
install(
4688
DIRECTORY include/
4789
DESTINATION include/joint_limits
4890
)
49-
install(TARGETS joint_limits
91+
install(TARGETS
92+
joint_limits
93+
joint_limiter_interface
94+
simple_joint_limiter
5095
EXPORT export_joint_limits
5196
ARCHIVE DESTINATION lib
5297
LIBRARY DESTINATION lib
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// Copyright (c) 2021, Stogl Robotics Consulting UG (haftungsbeschränkt)
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
/// \author Denis Stogl
16+
17+
#ifndef JOINT_LIMITS__JOINT_LIMITER_INTERFACE_HPP_
18+
#define JOINT_LIMITS__JOINT_LIMITER_INTERFACE_HPP_
19+
20+
#include <string>
21+
#include <vector>
22+
23+
#include "joint_limits/joint_limits.hpp"
24+
#include "joint_limits/visibility_control.h"
25+
#include "rclcpp/node.hpp"
26+
#include "trajectory_msgs/msg/joint_trajectory_point.hpp"
27+
28+
namespace joint_limits
29+
{
30+
template <typename LimitsType>
31+
class JointLimiterInterface
32+
{
33+
public:
34+
JOINT_LIMITS_PUBLIC JointLimiterInterface() = default;
35+
36+
JOINT_LIMITS_PUBLIC virtual ~JointLimiterInterface() = default;
37+
38+
/// Initialization of every JointLimiter.
39+
/**
40+
* Initialization of JointLimiter for defined joints with their names.
41+
* Robot description topic provides a topic name where URDF of the robot can be found.
42+
* This is needed to use joint limits from URDF (not implemented yet!).
43+
* Override this method only if Initialization and reading joint limits should be adapted.
44+
* Otherwise, initialize your custom limiter in `on_limit` method.
45+
*
46+
* \param[in] joint_names names of joints where limits should be applied.
47+
* \param[in] node shared pointer to the node where joint limit parameters defined.
48+
* \param[in] robot_description_topic string of a topic where robot description is accessible.
49+
*
50+
*/
51+
JOINT_LIMITS_PUBLIC virtual bool init(
52+
const std::vector<std::string> joint_names, const rclcpp::Node::SharedPtr & node,
53+
const std::string & robot_description_topic = "/robot_description");
54+
55+
JOINT_LIMITS_PUBLIC virtual bool configure(
56+
const trajectory_msgs::msg::JointTrajectoryPoint & current_joint_states)
57+
{
58+
return on_configure(current_joint_states);
59+
}
60+
61+
JOINT_LIMITS_PUBLIC virtual bool enforce(
62+
trajectory_msgs::msg::JointTrajectoryPoint & current_joint_states,
63+
trajectory_msgs::msg::JointTrajectoryPoint & desired_joint_states, const rclcpp::Duration & dt)
64+
{
65+
// TODO(destogl): add checks if sizes of vectors and number of limits correspond.
66+
return on_enforce(current_joint_states, desired_joint_states, dt);
67+
}
68+
69+
// TODO(destogl): Make those protected?
70+
// Methods that each limiter implementation has to implement
71+
JOINT_LIMITS_PUBLIC virtual bool on_init() { return true; }
72+
73+
JOINT_LIMITS_PUBLIC virtual bool on_configure(
74+
const trajectory_msgs::msg::JointTrajectoryPoint & /*current_joint_states*/)
75+
{
76+
return true;
77+
}
78+
79+
JOINT_LIMITS_PUBLIC virtual bool on_enforce(
80+
trajectory_msgs::msg::JointTrajectoryPoint & current_joint_states,
81+
trajectory_msgs::msg::JointTrajectoryPoint & desired_joint_states,
82+
const rclcpp::Duration & dt) = 0;
83+
84+
protected:
85+
size_t number_of_joints_;
86+
std::vector<LimitsType> joint_limits_;
87+
rclcpp::Node::SharedPtr node_;
88+
};
89+
90+
} // namespace joint_limits
91+
92+
#endif // JOINT_LIMITS__JOINT_LIMITER_INTERFACE_HPP_
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright (c) 2021, PickNik Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
/// \author Denis Stogl
16+
17+
#ifndef JOINT_LIMITS__SIMPLE_JOINT_LIMITER_HPP_
18+
#define JOINT_LIMITS__SIMPLE_JOINT_LIMITER_HPP_
19+
20+
#include <string>
21+
22+
#include "joint_limits/joint_limiter_interface.hpp"
23+
#include "joint_limits/joint_limits.hpp"
24+
25+
namespace joint_limits
26+
{
27+
template <typename LimitsType>
28+
class SimpleJointLimiter : public JointLimiterInterface<JointLimits>
29+
{
30+
public:
31+
JOINT_LIMITS_PUBLIC SimpleJointLimiter();
32+
33+
JOINT_LIMITS_PUBLIC bool on_enforce(
34+
trajectory_msgs::msg::JointTrajectoryPoint & current_joint_states,
35+
trajectory_msgs::msg::JointTrajectoryPoint & desired_joint_states,
36+
const rclcpp::Duration & dt) override;
37+
};
38+
39+
} // namespace joint_limits
40+
41+
#endif // JOINT_LIMITS__SIMPLE_JOINT_LIMITER_HPP_
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright (c) 2021, Stogl Robotics Consulting UG (haftungsbeschränkt)
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#ifndef JOINT_LIMITS__VISIBILITY_CONTROL_H_
16+
#define JOINT_LIMITS__VISIBILITY_CONTROL_H_
17+
18+
// This logic was borrowed (then namespaced) from the examples on the gcc wiki:
19+
// https://gcc.gnu.org/wiki/Visibility
20+
21+
#if defined _WIN32 || defined __CYGWIN__
22+
#ifdef __GNUC__
23+
#define JOINT_LIMITS_EXPORT __attribute__((dllexport))
24+
#define JOINT_LIMITS_IMPORT __attribute__((dllimport))
25+
#else
26+
#define JOINT_LIMITS_EXPORT __declspec(dllexport)
27+
#define JOINT_LIMITS_IMPORT __declspec(dllimport)
28+
#endif
29+
#ifdef JOINT_LIMITS_BUILDING_DLL
30+
#define JOINT_LIMITS_PUBLIC JOINT_LIMITS_EXPORT
31+
#else
32+
#define JOINT_LIMITS_PUBLIC JOINT_LIMITS_IMPORT
33+
#endif
34+
#define JOINT_LIMITS_PUBLIC_TYPE JOINT_LIMITS_PUBLIC
35+
#define JOINT_LIMITS_LOCAL
36+
#else
37+
#define JOINT_LIMITS_EXPORT __attribute__((visibility("default")))
38+
#define JOINT_LIMITS_IMPORT
39+
#if __GNUC__ >= 4
40+
#define JOINT_LIMITS_PUBLIC __attribute__((visibility("default")))
41+
#define JOINT_LIMITS_LOCAL __attribute__((visibility("hidden")))
42+
#else
43+
#define JOINT_LIMITS_PUBLIC
44+
#define JOINT_LIMITS_LOCAL
45+
#endif
46+
#define JOINT_LIMITS_PUBLIC_TYPE
47+
#endif
48+
49+
#endif // JOINT_LIMITS__VISIBILITY_CONTROL_H_

joint_limits/joint_limiters.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<library path="simple_joint_limiter">
2+
<class name="joint_limits/SimpleJointLimiter"
3+
type="joint_limits::SimpleJointLimiter&lt;joint_limits::JointLimits&gt;"
4+
base_class_type="joint_limits::JointLimiterInterface&lt;joint_limits::JointLimits&gt;">
5+
<description>
6+
Simple joint limiter using clamping approach.
7+
</description>
8+
</class>
9+
</library>

joint_limits/package.xml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
<package format="3">
22
<name>joint_limits</name>
33
<version>3.9.0</version>
4-
<description>Interfaces for handling of joint limits for controllers or hardware.</description>
4+
<description>Package for with interfaces for handling of joint limits for use in controllers or in hardware. The package also implements a simple, default joint limit strategy by clamping the values.</description>
55

66
<maintainer email="[email protected]">Bence Magyar</maintainer>
7-
<maintainer email="denis@stogl.de">Denis Štogl</maintainer>
7+
<maintainer email="denis.stogl@stoglrobotics.de">Denis Štogl</maintainer>
88

99
<license>Apache License 2.0</license>
1010

@@ -14,11 +14,14 @@
1414

1515
<buildtool_depend>ament_cmake</buildtool_depend>
1616

17+
<depend>pluginlib</depend>
1718
<depend>rclcpp</depend>
1819
<depend>rclcpp_lifecycle</depend>
20+
<depend>trajectory_msgs</depend>
1921

20-
<test_depend>launch_testing_ament_cmake</test_depend>
22+
<test_depend>ament_cmake_gmock</test_depend>
2123
<test_depend>ament_cmake_gtest</test_depend>
24+
<test_depend>launch_testing_ament_cmake</test_depend>
2225

2326
<export>
2427
<build_type>ament_cmake</build_type>
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// Copyright (c) 2021, Stogl Robotics Consulting UG (haftungsbeschränkt)
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
/// \author Denis Stogl
16+
17+
#include "joint_limits/joint_limiter_interface.hpp"
18+
19+
#include <string>
20+
#include <vector>
21+
22+
#include "joint_limits/joint_limits_rosparam.hpp"
23+
24+
// TODO(anyone): Add handing of SoftLimits
25+
namespace joint_limits
26+
{
27+
template <>
28+
bool JointLimiterInterface<JointLimits>::init(
29+
const std::vector<std::string> joint_names, const rclcpp::Node::SharedPtr & node,
30+
const std::string & /*robot_description_topic*/)
31+
{
32+
number_of_joints_ = joint_names.size();
33+
joint_limits_.resize(number_of_joints_);
34+
node_ = node;
35+
36+
bool result = true;
37+
38+
// TODO(destogl): get limits from URDF
39+
40+
// Initialize and get joint limits from parameter server
41+
for (auto i = 0ul; i < number_of_joints_; ++i)
42+
{
43+
if (!declare_parameters(joint_names[i], node))
44+
{
45+
RCLCPP_ERROR(
46+
node->get_logger(), "JointLimiter: Joint '%s': parameter declaration has failed",
47+
joint_names[i].c_str());
48+
result = false;
49+
break;
50+
}
51+
if (!joint_limits::get_joint_limits(joint_names[i], node, joint_limits_[i]))
52+
{
53+
RCLCPP_ERROR(
54+
node->get_logger(), "JointLimiter: Joint '%s': getting parameters has failed",
55+
joint_names[i].c_str());
56+
result = false;
57+
break;
58+
}
59+
RCLCPP_INFO(
60+
node->get_logger(), "Joint '%s':\n%s", joint_names[i].c_str(),
61+
joint_limits_[i].to_string().c_str());
62+
}
63+
64+
if (result)
65+
{
66+
result = on_init();
67+
}
68+
69+
return result;
70+
}
71+
72+
} // namespace joint_limits

0 commit comments

Comments
 (0)