Skip to content

Commit 2f725a5

Browse files
authored
Merge pull request #279 from compas-dev/ros-noetic-support
Add support for ROS Noetic
2 parents 1f2eda7 + 1400348 commit 2f725a5

File tree

9 files changed

+48
-7
lines changed

9 files changed

+48
-7
lines changed

CHANGELOG.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,14 @@ Unreleased
1212

1313
**Added**
1414

15+
* Added support for MoveIt on ROS Noetic
16+
1517
**Changed**
1618

1719
**Fixed**
1820

1921
* Fix ``repr()`` of ``ROSmsg`` class
22+
* Fix data type of secs and nsecs in ``Time`` ROS message
2023

2124
**Deprecated**
2225

README.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ COMPAS FAB: Robotic Fabrication for COMPAS
3030
.. image:: https://zenodo.org/badge/107952684.svg
3131
:target: https://zenodo.org/badge/latestdoi/107952684
3232

33+
.. image:: https://img.shields.io/twitter/follow/compas_dev?style=social
34+
:target: https://twitter.com/compas_dev
35+
:alt: Twitter Follow
36+
3337
.. end-badges
3438
3539
**Robotic fabrication package for the COMPAS Framework** that facilitates the

setup.cfg

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ line_length = 180
4141
known_first_party = compas_fab
4242
default_section = THIRDPARTY
4343
forced_separate = test_compas_fab
44-
not_skip = __init__.py
4544
skip = migrations
4645

4746
[coverage:run]

src/compas_fab/backends/ros/backend_features/move_it_inverse_kinematics.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
from compas.utilities import await_callback
66

77
from compas_fab.backends.interfaces import InverseKinematics
8-
from compas_fab.backends.ros.backend_features.helpers import validate_response
98
from compas_fab.backends.ros.backend_features.helpers import convert_constraints_to_rosmsg
9+
from compas_fab.backends.ros.backend_features.helpers import validate_response
10+
from compas_fab.backends.ros.messages import RosDistro
1011
from compas_fab.backends.ros.messages import AttachedCollisionObject
1112
from compas_fab.backends.ros.messages import GetPositionIKRequest
1213
from compas_fab.backends.ros.messages import GetPositionIKResponse
@@ -18,6 +19,7 @@
1819
from compas_fab.backends.ros.messages import PositionIKRequest
1920
from compas_fab.backends.ros.messages import RobotState
2021
from compas_fab.backends.ros.service_description import ServiceDescription
22+
from compas_fab.robots import Duration
2123

2224
__all__ = [
2325
'MoveItInverseKinematics',
@@ -61,10 +63,12 @@ def inverse_kinematics(self, robot, frame_WCF, start_configuration=None, group=N
6163
- ``"constraints"``: (:obj:`list` of :class:`compas_fab.robots.Constraint`, optional)
6264
A set of constraints that the request must obey.
6365
Defaults to ``None``.
64-
- ``"attempts"``: (:obj:`int`, optional) The maximum number of inverse kinematic attempts.
65-
Defaults to ``8``.
66+
- ``"timeout"``: (:obj:`int`, optional) Maximum allowed time for inverse kinematic calculation in seconds.
67+
Defaults to ``2``. This value supersedes the ``"attempts"`` argument used before ROS Noetic.
6668
- ``"attached_collision_meshes"``: (:obj:`list` of :class:`compas_fab.robots.AttachedCollisionMesh`, optional)
6769
Defaults to ``None``.
70+
- ``"attempts"``: (:obj:`int`, optional) The maximum number of inverse kinematic attempts.
71+
Defaults to ``8``. This value is ignored on ROS Noetic and newer, use ``"timeout"`` instead.
6872
6973
Raises
7074
------
@@ -108,12 +112,22 @@ def inverse_kinematics_async(self, callback, errback,
108112

109113
constraints = convert_constraints_to_rosmsg(options.get('constraints'), header)
110114

115+
timeout_in_secs = options.get('timeout', 2)
116+
timeout_duration = Duration(timeout_in_secs, 0).to_data()
117+
111118
ik_request = PositionIKRequest(group_name=group,
112119
robot_state=start_state,
113120
constraints=constraints,
114121
pose_stamped=pose_stamped,
115122
avoid_collisions=options.get('avoid_collisions', True),
116-
attempts=options.get('attempts', 8))
123+
attempts=options.get('attempts', 8),
124+
timeout=timeout_duration)
125+
126+
# The field `attempts` was removed in Noetic (and higher)
127+
# so it needs to be removed from the message otherwise it causes a serialization error
128+
# https://github.com/ros-planning/moveit/pull/1288
129+
if self.ros_client.ros_distro not in (RosDistro.KINETIC, RosDistro.MELODIC):
130+
del ik_request.attempts
117131

118132
def convert_to_positions(response):
119133
callback((response.solution.joint_state.position, response.solution.joint_state.name))

src/compas_fab/backends/ros/client.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from compas.robots import RobotModel
66
from roslibpy import Message
7+
from roslibpy import Param
78
from roslibpy import Ros
89
from roslibpy.actionlib import ActionClient
910
from roslibpy.actionlib import Goal
@@ -142,6 +143,7 @@ def __init__(self, host='localhost', port=9090, is_secure=False, planner_backend
142143

143144
planner_backend_type = PLANNER_BACKENDS[planner_backend]
144145
self.planner = planner_backend_type(self)
146+
self._ros_distro = None
145147

146148
def __enter__(self):
147149
self.run()
@@ -151,6 +153,14 @@ def __enter__(self):
151153
def __exit__(self, *args):
152154
self.close()
153155

156+
@property
157+
def ros_distro(self):
158+
"""Retrieves the ROS version to which the client is connected (eg. kinetic)"""
159+
if not self._ros_distro:
160+
self._ros_distro = Param(self, '/rosdistro').get(timeout=1)
161+
162+
return self._ros_distro
163+
154164
def load_robot(self, load_geometry=False, urdf_param_name='/robot_description', srdf_param_name='/robot_description_semantic', precision=None, local_cache_directory=None):
155165
"""Load an entire robot instance -including model and semantics- directly from ROS.
156166

src/compas_fab/backends/ros/messages/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from .moveit_msgs import * # noqa: F401,F403
77
from .object_recognition_msgs import * # noqa: F401,F403
88
from .octomap_msgs import * # noqa: F401,F403
9+
from .ros_releases import * # noqa: F401,F403
910
from .sensor_msgs import * # noqa: F401,F403
1011
from .services import * # noqa: F401,F403
1112
from .shape_msgs import * # noqa: F401,F403

src/compas_fab/backends/ros/messages/moveit_msgs.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ class PositionIKRequest(ROSmsg):
185185
"""
186186

187187
def __init__(self, group_name="robot", robot_state=None, constraints=None,
188-
pose_stamped=None, timeout=1.0, attempts=8,
188+
pose_stamped=None, timeout=None, attempts=8,
189189
avoid_collisions=True):
190190
self.group_name = group_name
191191
self.robot_state = robot_state if robot_state else RobotState()
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from __future__ import absolute_import
2+
3+
4+
class RosDistro(object):
5+
"""Supported/recognized ROS distros"""
6+
KINETIC = 'kinetic'
7+
MELODIC = 'melodic'
8+
NOETIC = 'noetic'
9+
10+
SUPPORTED_DISTROS = tuple([KINETIC, MELODIC, NOETIC])

src/compas_fab/backends/ros/messages/std_msgs.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class Time(ROSmsg):
4343
"""https://docs.ros.org/kinetic/api/std_msgs/html/msg/Time.html
4444
"""
4545

46-
def __init__(self, secs=0., nsecs=0.):
46+
def __init__(self, secs=0, nsecs=0):
4747
self.secs = secs
4848
self.nsecs = nsecs
4949

0 commit comments

Comments
 (0)