moveit2
The MoveIt Motion Planning Framework for ROS 2.
Loading...
Searching...
No Matches
planning_scene_monitor.hpp
Go to the documentation of this file.
1/*********************************************************************
2 * Software License Agreement (BSD License)
3 *
4 * Copyright (c) 2011, Willow Garage, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
17 * * Neither the name of Willow Garage nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 *********************************************************************/
34
35/* Author: Ioan Sucan */
36
37#pragma once
38
39#include <rclcpp/rclcpp.hpp>
40#include <rclcpp/version.h>
41// For Rolling, Kilted, and newer
42#if RCLCPP_VERSION_GTE(29, 6, 0)
43#include <tf2_ros/buffer.hpp>
44#include <tf2_ros/transform_listener.hpp>
45// For Jazzy and older
46#else
47#include <tf2_ros/buffer.h>
48#include <tf2_ros/transform_listener.h>
49#endif
56#include <moveit_msgs/srv/get_planning_scene.hpp>
57#include <memory>
58#include <thread>
59#include <shared_mutex>
60#include <mutex>
61#include <thread>
62
63#include <moveit_planning_scene_monitor_export.h>
64
66{
67MOVEIT_CLASS_FORWARD(PlanningSceneMonitor); // Defines PlanningSceneMonitorPtr, ConstPtr, WeakPtr... etc
68
72class MOVEIT_PLANNING_SCENE_MONITOR_EXPORT PlanningSceneMonitor
73{
74public:
79
84
86 {
88 UPDATE_NONE = 0,
89
91 UPDATE_STATE = 1,
92
94 UPDATE_TRANSFORMS = 2,
95
98 UPDATE_GEOMETRY = 4,
99
101 UPDATE_SCENE = 8 + UPDATE_STATE + UPDATE_TRANSFORMS + UPDATE_GEOMETRY
102 };
103
105 static const std::string DEFAULT_JOINT_STATES_TOPIC; // "/joint_states"
106
108 static const std::string DEFAULT_ATTACHED_COLLISION_OBJECT_TOPIC; // "/attached_collision_object"
109
111 static const std::string DEFAULT_COLLISION_OBJECT_TOPIC; // "/collision_object"
112
115 static const std::string DEFAULT_PLANNING_SCENE_WORLD_TOPIC; // "/planning_scene_world"
116
118 static const std::string DEFAULT_PLANNING_SCENE_TOPIC; // "/planning_scene"
119
121 static const std::string DEFAULT_PLANNING_SCENE_SERVICE; // "/get_planning_scene"
122
125 static const std::string MONITORED_PLANNING_SCENE_TOPIC; // "monitored_planning_scene"
126
131 PlanningSceneMonitor(const rclcpp::Node::SharedPtr& node, const std::string& robot_description,
132 const std::string& name = "");
133
138 PlanningSceneMonitor(const rclcpp::Node::SharedPtr& node, const robot_model_loader::RobotModelLoaderPtr& rml,
139 const std::string& name = "");
140
146 PlanningSceneMonitor(const rclcpp::Node::SharedPtr& node, const planning_scene::PlanningScenePtr& scene,
147 const std::string& robot_description, const std::string& name = "");
148
154 PlanningSceneMonitor(const rclcpp::Node::SharedPtr& node, const planning_scene::PlanningScenePtr& scene,
155 const robot_model_loader::RobotModelLoaderPtr& rml, const std::string& name = "");
156
158
160 const std::string& getName() const
161 {
162 return monitor_name_;
163 }
164
166 const robot_model_loader::RobotModelLoaderPtr& getRobotModelLoader() const
167 {
168 return rm_loader_;
169 }
170
171 const moveit::core::RobotModelConstPtr& getRobotModel() const
172 {
173 return robot_model_;
174 }
175
190 const planning_scene::PlanningScenePtr& getPlanningScene()
191 {
192 return scene_;
193 }
194
198 const planning_scene::PlanningSceneConstPtr& getPlanningScene() const
199 {
200 return scene_const_;
201 }
202
204 planning_scene::PlanningScenePtr
205 copyPlanningScene(const moveit_msgs::msg::PlanningScene& diff = moveit_msgs::msg::PlanningScene());
206
211 bool updatesScene(const planning_scene::PlanningSceneConstPtr& scene) const;
212
217 bool updatesScene(const planning_scene::PlanningScenePtr& scene) const;
218
221 const std::string& getRobotDescription() const
222 {
223 return robot_description_;
224 }
225
228 {
229 return default_robot_padd_;
230 }
231
233 double getDefaultRobotScale() const
234 {
235 return default_robot_scale_;
236 }
237
240 {
241 return default_object_padd_;
242 }
243
246 {
247 return default_attached_padd_;
248 }
249
251 const std::shared_ptr<tf2_ros::Buffer>& getTFClient() const
252 {
253 return tf_buffer_;
254 }
255
261 void monitorDiffs(bool flag);
262
266 void startPublishingPlanningScene(SceneUpdateType event,
267 const std::string& planning_scene_topic = MONITORED_PLANNING_SCENE_TOPIC);
268
270 void stopPublishingPlanningScene();
271
273 void setPlanningScenePublishingFrequency(double hz);
274
277 {
278 return publish_planning_scene_frequency_;
279 }
280
283 const CurrentStateMonitorPtr& getStateMonitor() const
284 {
285 return current_state_monitor_;
286 }
287
288 CurrentStateMonitorPtr& getStateMonitorNonConst()
289 {
290 return current_state_monitor_;
291 }
292
298 void updateFrameTransforms();
299
303 void startStateMonitor(const std::string& joint_states_topic = DEFAULT_JOINT_STATES_TOPIC,
304 const std::string& attached_objects_topic = DEFAULT_ATTACHED_COLLISION_OBJECT_TOPIC);
305
307 void stopStateMonitor();
308
313 void updateSceneWithCurrentState(bool skip_update_if_locked = false);
314
320 void setStateUpdateFrequency(double hz);
321
324 {
325 if (dt_state_update_.count() > 0.0)
326 {
327 return 1.0 / dt_state_update_.count();
328 }
329 else
330 {
331 return 0.0;
332 }
333 }
334
338 void startSceneMonitor(const std::string& scene_topic = DEFAULT_PLANNING_SCENE_TOPIC);
339
347 bool requestPlanningSceneState(const std::string& service_name = DEFAULT_PLANNING_SCENE_SERVICE);
348
356 void providePlanningSceneService(const std::string& service_name = DEFAULT_PLANNING_SCENE_SERVICE);
357
359 void stopSceneMonitor();
360
369 void startWorldGeometryMonitor(const std::string& collision_objects_topic = DEFAULT_COLLISION_OBJECT_TOPIC,
370 const std::string& planning_scene_world_topic = DEFAULT_PLANNING_SCENE_WORLD_TOPIC,
371 const bool load_octomap_monitor = true);
372
374 void stopWorldGeometryMonitor();
375
377 void addUpdateCallback(const std::function<void(SceneUpdateType)>& fn);
378
380 void clearUpdateCallbacks();
381
383 void getMonitoredTopics(std::vector<std::string>& topics) const;
384
386 const rclcpp::Time& getLastUpdateTime() const
387 {
388 return last_update_time_;
389 }
390
391 void publishDebugInformation(bool flag);
392
394 void triggerSceneUpdateEvent(SceneUpdateType update_type);
395
401 bool waitForCurrentRobotState(const rclcpp::Time& t, double wait_time = 1.);
402
403 void clearOctomap();
404
405 // Called to update the planning scene with a new message.
406 bool newPlanningSceneMessage(const moveit_msgs::msg::PlanningScene& scene);
407
408 // Called to update a collision object in the planning scene.
409 bool processCollisionObjectMsg(const moveit_msgs::msg::CollisionObject::ConstSharedPtr& collision_object_msg,
410 const std::optional<moveit_msgs::msg::ObjectColor>& color_msg = std::nullopt);
411
412 // Called to update an attached collision object in the planning scene.
413 bool processAttachedCollisionObjectMsg(
414 const moveit_msgs::msg::AttachedCollisionObject::ConstSharedPtr& attached_collision_object_msg);
415
416protected:
420 void initialize(const planning_scene::PlanningScenePtr& scene);
421
423 void lockSceneRead();
424
426 void unlockSceneRead();
427
430 void lockSceneWrite();
431
434 void unlockSceneWrite();
435
437 void configureCollisionMatrix(const planning_scene::PlanningScenePtr& scene);
438
440 void configureDefaultPadding();
441
443 void newPlanningSceneWorldCallback(const moveit_msgs::msg::PlanningSceneWorld::ConstSharedPtr& world);
444
446 void octomapUpdateCallback();
447
449 void currentStateAttachedBodyUpdateCallback(moveit::core::AttachedBody* attached_body, bool just_attached);
450
452 void currentWorldObjectUpdateCallback(const collision_detection::World::ObjectConstPtr& object,
454
455 void includeRobotLinksInOctree();
456 void excludeRobotLinksFromOctree();
457
458 void excludeWorldObjectsFromOctree();
459 void includeWorldObjectsInOctree();
460 void excludeWorldObjectFromOctree(const collision_detection::World::ObjectConstPtr& obj);
461 void includeWorldObjectInOctree(const collision_detection::World::ObjectConstPtr& obj);
462
463 void excludeAttachedBodiesFromOctree();
464 void includeAttachedBodiesInOctree();
465 void excludeAttachedBodyFromOctree(const moveit::core::AttachedBody* attached_body);
466 void includeAttachedBodyInOctree(const moveit::core::AttachedBody* attached_body);
467
468 bool getShapeTransformCache(const std::string& target_frame, const rclcpp::Time& target_time,
470
472 std::string monitor_name_;
473
474 planning_scene::PlanningScenePtr scene_;
475 planning_scene::PlanningSceneConstPtr scene_const_;
476 planning_scene::PlanningScenePtr parent_scene_;
477 std::shared_mutex scene_update_mutex_;
478 rclcpp::Time last_update_time_;
480
481 std::shared_ptr<rclcpp::Node> node_;
482
483 // TODO: (anasarrak) callbacks on ROS2?
484 // https://answers.ros.org/question/300874/how-do-you-use-callbackgroups-as-a-replacement-for-callbackqueues-in-ros2/
485 // ros::CallbackQueue queue_;
486 std::shared_ptr<rclcpp::Node> pnode_;
487 std::shared_ptr<rclcpp::executors::SingleThreadedExecutor> private_executor_;
489
490 std::shared_ptr<tf2_ros::Buffer> tf_buffer_;
491 std::shared_ptr<tf2_ros::TransformListener> tf_listener_;
492
494
504 std::map<std::string, double> default_robot_link_padd_;
506 std::map<std::string, double> default_robot_link_scale_;
507
508 // variables for planning scene publishing
509 rclcpp::Publisher<moveit_msgs::msg::PlanningScene>::SharedPtr planning_scene_publisher_;
510 std::unique_ptr<std::thread> publish_planning_scene_;
513 std::atomic<SceneUpdateType> new_scene_update_;
514 std::condition_variable_any new_scene_update_condition_;
515
516 // subscribe to various sources of data
517 rclcpp::Subscription<moveit_msgs::msg::PlanningScene>::SharedPtr planning_scene_subscriber_;
518 rclcpp::Subscription<moveit_msgs::msg::PlanningSceneWorld>::SharedPtr planning_scene_world_subscriber_;
519
520 rclcpp::Subscription<moveit_msgs::msg::AttachedCollisionObject>::SharedPtr attached_collision_object_subscriber_;
521 rclcpp::Subscription<moveit_msgs::msg::CollisionObject>::SharedPtr collision_object_subscriber_;
522
523 // provide an optional service to get the full planning scene state
524 // this is used by MoveGroup and related application nodes
525 rclcpp::Service<moveit_msgs::srv::GetPlanningScene>::SharedPtr get_scene_service_;
526
527 // include a octomap monitor
528 std::unique_ptr<occupancy_map_monitor::OccupancyMapMonitor> octomap_monitor_;
529
530 // include a current state monitor
531 CurrentStateMonitorPtr current_state_monitor_;
532
533 typedef std::map<const moveit::core::LinkModel*,
534 std::vector<std::pair<occupancy_map_monitor::ShapeHandle, std::size_t> > >
537 std::vector<std::pair<occupancy_map_monitor::ShapeHandle, std::size_t> > >;
539 std::map<std::string, std::vector<std::pair<occupancy_map_monitor::ShapeHandle, const Eigen::Isometry3d*> > >;
540
544 mutable std::recursive_mutex shape_handles_lock_;
545
547 std::recursive_mutex update_lock_;
548 std::vector<std::function<void(SceneUpdateType)> > update_callbacks_;
550
551private:
552 void getUpdatedFrameTransforms(std::vector<geometry_msgs::msg::TransformStamped>& transforms);
553
554 // publish planning scene update diffs (runs in its own thread)
555 void scenePublishingThread();
556
557 // called by current_state_monitor_ when robot state (as monitored on joint state topic) changes
558 void onStateUpdate(const sensor_msgs::msg::JointState::ConstSharedPtr& joint_state);
559
560 // called by state_update_timer_ when a state update it pending
561 void stateUpdateTimerCallback();
562
563 // Callback for a new planning scene msg
564 void newPlanningSceneCallback(const moveit_msgs::msg::PlanningScene::ConstSharedPtr& scene);
565
566 // Callback for requesting the full planning scene via service
567 void getPlanningSceneServiceCallback(const moveit_msgs::srv::GetPlanningScene::Request::SharedPtr& req,
568 const moveit_msgs::srv::GetPlanningScene::Response::SharedPtr& res);
569
570 void updatePublishSettings(bool publish_geom_updates, bool publish_state_updates, bool publish_transform_updates,
571 bool publish_planning_scene, double publish_planning_scene_hz);
572
574 std::atomic<bool> state_update_pending_;
575
576 // Lock for writing last_robot_state_update_wall_time_ and dt_state_update_
577 std::mutex state_update_mutex_;
578
580 // Only access this from callback functions (and constructor)
581 // This field is protected by state_update_mutex_
582 std::chrono::system_clock::time_point last_robot_state_update_wall_time_;
583
585 // This field is protected by state_update_mutex_
586 std::chrono::duration<double> dt_state_update_; // 1hz
587
589 // Setting this to a non-zero value resolves issues when the sensor data is
590 // arriving so fast that it is preceding the transform state.
591 rclcpp::Duration shape_transform_cache_lookup_wait_time_;
592
594 // If state_update_pending_ is true, call updateSceneWithCurrentState()
595 // Not safe to access from callback functions.
596 rclcpp::TimerBase::SharedPtr state_update_timer_;
597
598 robot_model_loader::RobotModelLoaderPtr rm_loader_;
599 moveit::core::RobotModelConstPtr robot_model_;
600
602
603 rclcpp::node_interfaces::OnSetParametersCallbackHandle::SharedPtr callback_handler_;
604
605 bool use_sim_time_;
606
609
610 rclcpp::Logger logger_;
611};
612
635{
636public:
637 LockedPlanningSceneRO(const PlanningSceneMonitorPtr& planning_scene_monitor)
639 {
640 initialize(true);
641 }
642
643 const PlanningSceneMonitorPtr& getPlanningSceneMonitor()
644 {
646 }
647
648 operator bool() const
649 {
650 return planning_scene_monitor_ && planning_scene_monitor_->getPlanningScene();
651 }
652
653 operator const planning_scene::PlanningSceneConstPtr&() const
654 {
655 return static_cast<const PlanningSceneMonitor*>(planning_scene_monitor_.get())->getPlanningScene();
656 }
657
658 const planning_scene::PlanningSceneConstPtr& operator->() const
659 {
660 return static_cast<const PlanningSceneMonitor*>(planning_scene_monitor_.get())->getPlanningScene();
661 }
662
663protected:
664 LockedPlanningSceneRO(const PlanningSceneMonitorPtr& planning_scene_monitor, bool read_only)
666 {
667 initialize(read_only);
668 }
669
670 void initialize(bool read_only)
671 {
673 lock_ = std::make_shared<SingleUnlock>(planning_scene_monitor_.get(), read_only);
674 }
675
677
678 // we use this struct so that lock/unlock are called only once
679 // even if the LockedPlanningScene instance is copied around
708
709 PlanningSceneMonitorPtr planning_scene_monitor_;
710 SingleUnlockPtr lock_;
711};
712
735{
736public:
737 LockedPlanningSceneRW(const PlanningSceneMonitorPtr& planning_scene_monitor)
739 {
740 }
741
742 operator const planning_scene::PlanningScenePtr&()
743 {
744 return planning_scene_monitor_->getPlanningScene();
745 }
746
747 const planning_scene::PlanningScenePtr& operator->()
748 {
749 return planning_scene_monitor_->getPlanningScene();
750 }
751};
752} // namespace planning_scene_monitor
#define MOVEIT_CLASS_FORWARD(C)
Represents an action that occurred on an object in the world. Several bits may be set indicating seve...
Definition world.hpp:268
Object defining bodies that can be attached to robot links.
A link from the robot. Contains the constant transform applied to the link and its geometry.
This is a convenience class for obtaining access to an instance of a locked PlanningScene.
LockedPlanningSceneRO(const PlanningSceneMonitorPtr &planning_scene_monitor, bool read_only)
LockedPlanningSceneRO(const PlanningSceneMonitorPtr &planning_scene_monitor)
const planning_scene::PlanningSceneConstPtr & operator->() const
const PlanningSceneMonitorPtr & getPlanningSceneMonitor()
This is a convenience class for obtaining access to an instance of a locked PlanningScene.
const planning_scene::PlanningScenePtr & operator->()
LockedPlanningSceneRW(const PlanningSceneMonitorPtr &planning_scene_monitor)
PlanningSceneMonitor Subscribes to the topic planning_scene.
static const std::string DEFAULT_PLANNING_SCENE_TOPIC
The name of the topic used by default for receiving full planning scenes or planning scene diffs.
void lockSceneRead()
Lock the scene for reading (multiple threads can lock for reading at the same time)
void lockSceneWrite()
Lock the scene for writing (only one thread can lock for writing and no other thread can lock for rea...
void unlockSceneRead()
Unlock the scene from reading (multiple threads can lock for reading at the same time)
static const std::string DEFAULT_PLANNING_SCENE_SERVICE
The name of the service used by default for requesting full planning scene state.
std::unique_ptr< occupancy_map_monitor::OccupancyMapMonitor > octomap_monitor_
std::map< std::string, double > default_robot_link_padd_
default robot link padding
static const std::string DEFAULT_ATTACHED_COLLISION_OBJECT_TOPIC
The name of the topic used by default for attached collision objects.
const planning_scene::PlanningSceneConstPtr & getPlanningScene() const
Avoid this function! Returns an unsafe pointer to the current planning scene.
static const std::string DEFAULT_COLLISION_OBJECT_TOPIC
The name of the topic used by default for receiving collision objects in the world.
PlanningSceneMonitor(const PlanningSceneMonitor &)=delete
PlanningSceneMonitor cannot be copy-constructed.
rclcpp::Subscription< moveit_msgs::msg::AttachedCollisionObject >::SharedPtr attached_collision_object_subscriber_
std::map< std::string, std::vector< std::pair< occupancy_map_monitor::ShapeHandle, const Eigen::Isometry3d * > > > CollisionBodyShapeHandles
rclcpp::Service< moveit_msgs::srv::GetPlanningScene >::SharedPtr get_scene_service_
std::map< const moveit::core::LinkModel *, std::vector< std::pair< occupancy_map_monitor::ShapeHandle, std::size_t > > > LinkShapeHandles
double getDefaultAttachedObjectPadding() const
Get the default attached padding.
planning_scene::PlanningSceneConstPtr scene_const_
PlanningSceneMonitor & operator=(const PlanningSceneMonitor &)=delete
PlanningSceneMonitor cannot be copy-assigned.
rclcpp::Subscription< moveit_msgs::msg::CollisionObject >::SharedPtr collision_object_subscriber_
rclcpp::Subscription< moveit_msgs::msg::PlanningScene >::SharedPtr planning_scene_subscriber_
double getDefaultRobotPadding() const
Get the default robot padding.
std::shared_mutex scene_update_mutex_
if diffs are monitored, this is the pointer to the parent scene
const moveit::core::RobotModelConstPtr & getRobotModel() const
std::shared_ptr< tf2_ros::TransformListener > tf_listener_
double getStateUpdateFrequency() const
Get the maximum frequency (Hz) at which the current state of the planning scene is updated.
std::shared_ptr< rclcpp::executors::SingleThreadedExecutor > private_executor_
const rclcpp::Time & getLastUpdateTime() const
Return the time when the last update was made to the planning scene (by any monitor)
const CurrentStateMonitorPtr & getStateMonitor() const
Get the stored instance of the stored current state monitor.
std::map< const moveit::core::AttachedBody *, std::vector< std::pair< occupancy_map_monitor::ShapeHandle, std::size_t > > > AttachedBodyShapeHandles
double getDefaultObjectPadding() const
Get the default object padding.
std::map< std::string, double > default_robot_link_scale_
default robot link scale
rclcpp::Time last_robot_motion_time_
Last time the state was updated.
double getDefaultRobotScale() const
Get the default robot scaling.
std::string monitor_name_
The name of this scene monitor.
std::recursive_mutex update_lock_
lock access to update_callbacks_
rclcpp::Time last_update_time_
mutex for stored scene
const std::string & getRobotDescription() const
Get the stored robot description.
const std::string & getName() const
Get the name of this monitor.
const robot_model_loader::RobotModelLoaderPtr & getRobotModelLoader() const
Get the user kinematic model loader.
std::shared_ptr< rclcpp::Node > node_
Last time the robot has moved.
rclcpp::Publisher< moveit_msgs::msg::PlanningScene >::SharedPtr planning_scene_publisher_
static const std::string DEFAULT_JOINT_STATES_TOPIC
The name of the topic used by default for receiving joint states.
const planning_scene::PlanningScenePtr & getPlanningScene()
Avoid this function! Returns an unsafe pointer to the current planning scene.
const std::shared_ptr< tf2_ros::Buffer > & getTFClient() const
Get the instance of the TF client that was passed to the constructor of this class.
std::vector< std::function< void(SceneUpdateType)> > update_callbacks_
double getPlanningScenePublishingFrequency() const
Get the maximum frequency at which planning scenes are published (Hz)
void unlockSceneWrite()
Lock the scene from writing (only one thread can lock for writing and no other thread can lock for re...
rclcpp::Subscription< moveit_msgs::msg::PlanningSceneWorld >::SharedPtr planning_scene_world_subscriber_
std::map< ShapeHandle, Eigen::Isometry3d, std::less< ShapeHandle >, Eigen::aligned_allocator< std::pair< const ShapeHandle, Eigen::Isometry3d > > > ShapeTransformCache
SingleUnlock(PlanningSceneMonitor *planning_scene_monitor, bool read_only)