42 #include <boost/program_options/cmdline.hpp>
43 #include <boost/program_options/options_description.hpp>
44 #include <boost/program_options/parsers.hpp>
45 #include <boost/program_options/variables_map.hpp>
46 #include <fmt/format.h>
47 #include <tf2_ros/transform_listener.h>
48 #include <rclcpp/executors.hpp>
49 #include <rclcpp/experimental/buffers/intra_process_buffer.hpp>
50 #include <rclcpp/logger.hpp>
51 #include <rclcpp/logging.hpp>
52 #include <rclcpp/node.hpp>
53 #include <rclcpp/node_options.hpp>
54 #include <rclcpp/version.h>
55 #if RCLCPP_VERSION_GTE(20, 0, 0)
56 #include <rclcpp/event_handler.hpp>
58 #include <rclcpp/qos_event.hpp>
60 #include <rclcpp/subscription.hpp>
61 #include <rclcpp/utilities.hpp>
68 static const std::string ROBOT_DESCRIPTION =
"robot_description";
72 RCLCPP_INFO(
getLogger(),
"Received an update to the planning scene...");
78 moveit_msgs::msg::PlanningScene psmsg;
84 RCLCPP_INFO(
getLogger(),
"Scene '%s' was previously added. Not adding again.",
89 RCLCPP_INFO(
getLogger(),
"Scene name is empty. Not saving.");
97 RCLCPP_INFO(
getLogger(),
"Scene name is empty. Not saving planning request.");
105 if (msg.name.empty())
107 RCLCPP_INFO(
getLogger(),
"No name specified for constraints. Not saving.");
113 RCLCPP_INFO(
getLogger(),
"Replacing constraints '%s'", msg.name.c_str());
119 RCLCPP_INFO(
getLogger(),
"Adding constraints '%s'", msg.name.c_str());
126 std::vector<std::string> names;
128 std::set<std::string> names_set(names.begin(), names.end());
129 std::size_t n = names.size();
130 while (names_set.find(
"S" + std::to_string(n)) != names_set.end())
132 std::string
name =
"S" + std::to_string(n);
133 RCLCPP_INFO(
getLogger(),
"Adding robot state '%s'",
name.c_str());
137 int main(
int argc,
char** argv)
139 rclcpp::init(argc, argv);
140 rclcpp::NodeOptions node_options;
141 node_options.allow_undeclared_parameters(
true);
142 node_options.automatically_declare_parameters_from_overrides(
true);
143 rclcpp::Node::SharedPtr node = rclcpp::Node::make_shared(
"save_to_warehouse", node_options);
146 boost::program_options::options_description desc;
147 desc.add_options()(
"help",
"Show help message")(
"host", boost::program_options::value<std::string>(),
149 "DB.")(
"port", boost::program_options::value<std::size_t>(),
152 boost::program_options::variables_map vm;
153 boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
154 boost::program_options::notify(vm);
156 if (vm.count(
"help"))
158 std::cout << desc <<
'\n';
163 if (vm.count(
"host") && vm.count(
"port"))
164 conn->setParams(vm[
"host"].as<std::string>(), vm[
"port"].as<std::size_t>());
165 if (!conn->connect())
171 RCLCPP_ERROR(node->get_logger(),
"Unable to initialize PlanningSceneMonitor");
180 std::vector<std::string> names;
184 RCLCPP_INFO(node->get_logger(),
"There are no previously stored scenes");
188 RCLCPP_INFO(node->get_logger(),
"Previously stored scenes:");
189 for (
const std::string&
name : names)
190 RCLCPP_INFO(node->get_logger(),
" * %s",
name.c_str());
195 RCLCPP_INFO(node->get_logger(),
"There are no previously stored constraints");
199 RCLCPP_INFO(node->get_logger(),
"Previously stored constraints:");
200 for (
const std::string&
name : names)
201 RCLCPP_INFO(node->get_logger(),
" * %s",
name.c_str());
206 RCLCPP_INFO(node->get_logger(),
"There are no previously stored robot states");
210 RCLCPP_INFO(node->get_logger(),
"Previously stored robot states:");
211 for (
const std::string&
name : names)
212 RCLCPP_INFO(node->get_logger(),
" * %s",
name.c_str());
218 "motion_plan_request", rclcpp::SystemDefaultsQoS(),
220 auto constr_sub = node->create_subscription<moveit_msgs::msg::Constraints>(
221 "constraints", rclcpp::SystemDefaultsQoS(),
222 [&](
const moveit_msgs::msg::Constraints& msg) {
onConstraints(msg, cs); });
223 auto state_sub = node->create_subscription<moveit_msgs::msg::RobotState>(
224 "robot_state", rclcpp::SystemDefaultsQoS(),
225 [&](
const moveit_msgs::msg::RobotState& msg) {
onRobotState(msg, rs); });
227 std::vector<std::string> topics;
229 RCLCPP_INFO_STREAM(node->get_logger(),
230 "Listening for scene updates on topics " << fmt::format(
"{}", fmt::join(topics,
", ")));
231 RCLCPP_INFO_STREAM(node->get_logger(),
"Listening for planning requests on topic " << mplan_req_sub->get_topic_name());
232 RCLCPP_INFO_STREAM(node->get_logger(),
"Listening for named constraints on topic " << constr_sub->get_topic_name());
233 RCLCPP_INFO_STREAM(node->get_logger(),
"Listening for states on topic " << state_sub->get_topic_name());
void removeConstraints(const std::string &name, const std::string &robot="", const std::string &group="")
bool hasConstraints(const std::string &name, const std::string &robot="", const std::string &group="") const
void getKnownConstraints(std::vector< std::string > &names, const std::string &robot="", const std::string &group="") const
void addConstraints(const moveit_msgs::msg::Constraints &msg, const std::string &robot="", const std::string &group="")
void addPlanningQuery(const moveit_msgs::msg::MotionPlanRequest &planning_query, const std::string &scene_name, const std::string &query_name="")
void addPlanningScene(const moveit_msgs::msg::PlanningScene &scene)
void getPlanningSceneNames(std::vector< std::string > &names) const
bool hasPlanningScene(const std::string &name) const
void getKnownRobotStates(std::vector< std::string > &names, const std::string &robot="") const
void addRobotState(const moveit_msgs::msg::RobotState &msg, const std::string &name, const std::string &robot="")
PlanningSceneMonitor Subscribes to the topic planning_scene.
const planning_scene::PlanningScenePtr & getPlanningScene()
Avoid this function! Returns an unsafe pointer to the current planning scene.
void addUpdateCallback(const std::function< void(SceneUpdateType)> &fn)
Add a function to be called when an update to the scene is received.
void getMonitoredTopics(std::vector< std::string > &topics) const
Get the topic names that the monitor is listening to.
void startSceneMonitor(const std::string &scene_topic=DEFAULT_PLANNING_SCENE_TOPIC)
Start the scene monitor (ROS topic-based)
void startWorldGeometryMonitor(const std::string &collision_objects_topic=DEFAULT_COLLISION_OBJECT_TOPIC, const std::string &planning_scene_world_topic=DEFAULT_PLANNING_SCENE_WORLD_TOPIC, const bool load_octomap_monitor=true)
Start the OccupancyMapMonitor and listening for:
warehouse_ros::DatabaseConnection::Ptr loadDatabase(const rclcpp::Node::SharedPtr &node)
Load a database connection.
rclcpp::Logger getLogger(const std::string &name)
Creates a namespaced logger.
void setNodeLoggerName(const std::string &name)
Call once after creating a node to initialize logging namespaces.
moveit_msgs::msg::MotionPlanRequest MotionPlanRequest
void onRobotState(const moveit_msgs::msg::RobotState &msg, moveit_warehouse::RobotStateStorage &rs)
int main(int argc, char **argv)
void onSceneUpdate(planning_scene_monitor::PlanningSceneMonitor &psm, moveit_warehouse::PlanningSceneStorage &pss)
rclcpp::Logger getLogger()
void onMotionPlanRequest(const moveit_msgs::msg::MotionPlanRequest &req, planning_scene_monitor::PlanningSceneMonitor &psm, moveit_warehouse::PlanningSceneStorage &pss)
void onConstraints(const moveit_msgs::msg::Constraints &msg, moveit_warehouse::ConstraintsStorage &cs)