15 #include "nav2_waypoint_follower/plugins/photo_at_waypoint.hpp"
20 #include "pluginlib/class_list_macros.hpp"
22 #include "nav2_ros_common/node_utils.hpp"
24 namespace nav2_waypoint_follower
35 const nav2::LifecycleNode::WeakPtr & parent,
36 const std::string & plugin_name)
38 auto node = parent.lock();
40 curr_frame_msg_ = std::make_shared<sensor_msgs::msg::Image>();
42 std::string save_dir_as_string;
43 save_dir_as_string = node->declare_or_get_parameter(
44 plugin_name +
".save_dir", std::string(
"/tmp/waypoint_images"));
45 image_topic_ = node->declare_or_get_parameter(
46 plugin_name +
".image_topic", std::string(
"/camera/color/image_raw"));
47 image_format_ = node->declare_or_get_parameter(
48 plugin_name +
".image_format", std::string(
"png"));
49 is_enabled_ = node->declare_or_get_parameter(
50 plugin_name +
".enabled",
true);
53 save_dir_ = save_dir_as_string;
55 if (!std::filesystem::exists(save_dir_)) {
58 "Provided save directory for photo at waypoint plugin does not exist,"
59 "provided directory is: %s, the directory will be created automatically.",
62 if (!std::filesystem::create_directory(save_dir_)) {
65 "Failed to create directory!: %s required by photo at waypoint plugin, "
66 "exiting the plugin with failure!",
72 }
catch (
const std::exception & e) {
74 logger_,
"Exception (%s) thrown while attempting to create image capture directory."
75 " This task executor is being disabled as it cannot save images.", e.what());
81 logger_,
"Photo at waypoint plugin is disabled.");
84 logger_,
"Initializing photo at waypoint plugin, subscribing to camera topic named; %s",
85 image_topic_.c_str());
86 camera_image_subscriber_ = node->create_subscription<sensor_msgs::msg::Image>(
93 const geometry_msgs::msg::PoseStamped & curr_pose,
const int & curr_waypoint_index)
98 "Photo at waypoint plugin is disabled. Not performing anything"
104 std::filesystem::path file_name = std::to_string(
105 curr_waypoint_index) +
"_" +
106 std::to_string(curr_pose.header.stamp.sec) +
"." + image_format_;
107 std::filesystem::path full_path_image_path = save_dir_ / file_name;
110 std::lock_guard<std::mutex> guard(global_mutex_);
111 cv::Mat curr_frame_mat;
113 cv::imwrite(full_path_image_path.string().c_str(), curr_frame_mat);
116 "Photo has been taken successfully at waypoint %i", curr_waypoint_index);
117 }
catch (
const std::exception & e) {
120 "Couldn't take photo at waypoint %i! Caught exception: %s \n"
121 "Make sure that the image topic named: %s is valid and active!",
123 e.what(), image_topic_.c_str());
131 std::lock_guard<std::mutex> guard(global_mutex_);
132 curr_frame_msg_ = msg;
136 const sensor_msgs::msg::Image::ConstSharedPtr & msg,
139 cv_bridge::CvImageConstPtr cv_bridge_ptr = cv_bridge::toCvShare(msg, msg->encoding);
140 cv::Mat frame = cv_bridge_ptr->image;
141 if (msg->encoding ==
"rgb8") {
142 cv::cvtColor(frame, frame, cv::COLOR_RGB2BGR);
148 PLUGINLIB_EXPORT_CLASS(
Base class for creating a plugin in order to perform a specific task at waypoint arrivals.
static void deepCopyMsg2Mat(const sensor_msgs::msg::Image::ConstSharedPtr &msg, cv::Mat &mat)
given a shared pointer to sensor::msg::Image type, make a deep copy to inputted cv Mat
bool processAtWaypoint(const geometry_msgs::msg::PoseStamped &curr_pose, const int &curr_waypoint_index)
Override this to define the body of your task that you would like to execute once the robot arrived t...
void imageCallback(const sensor_msgs::msg::Image::ConstSharedPtr &msg)
void initialize(const nav2::LifecycleNode::WeakPtr &parent, const std::string &plugin_name)
declares and loads parameters used
PhotoAtWaypoint()
Construct a new Photo At Waypoint object.
~PhotoAtWaypoint()
Destroy the Photo At Waypoint object.