Hi The Construct team,
I am currently working on the course project for ROS2 Basics in 5 Days with C++. The course project uses ROS2 Foxy but I learned with Galactic in the course.
Currently I am integrating my /find_wall
Service Client and /record_odom
Action Client with the base Wall Follower program - and I need help with the integration.
I tried to Google my question but could not find favorable results. I will have to Google further.
In the meantime, if you could help me out that would be great !
I am still new to the shared pointers
and std::make_shared<...>()
concepts in C++.
I have my C++ classes as shown below and I have my questions commented along. I have marked my questions inside as 1
, 2
, 3
, 4
, 5
and 6
.
// #include(s)
class ServiceClient : public rclcpp::Node {
private:
// private variables
public:
// public variables
ServiceClient() : Node("service_client_node") {
// constructor statements
}
~ServiceClient() {}
bool is_service_done() const {
// statements
}
void call_service() {
// statements
}
void response_callback(rclcpp::Client<MyServiceMsg>::SharedFuture future) {
// statements
}
};
class ActionClient : public rclcpp::Node {
private:
// private variables
public:
// public variables
explicit ActionClient(
const rclcpp::NodeOptions &node_options = rclcpp::NodeOptions())
: Node("action_client_node", node_options) {
// constructor statements
}
~ActionClient() {}
bool is_goal_done() const {
// statements
}
void send_goal() {
// statements
}
void goal_response_callback(
std::shared_future<MyActionMsgGoalHandle::SharedPtr> future) {
// statements
}
void
result_callback(const MyActionMsgGoalHandle::WrappedResult &action_result) {
// statements
}
void feedback_callback(
MyActionMsgGoalHandle::SharedPtr,
const std::shared_ptr<const MyActionMsg::Feedback> action_feedback) {
// statements
}
};
class MyRobot : public rclcpp::Node {
private:
// private variables
public:
// public variables
MyRobot() : Node("my_robot_node") {
cmd_vel_pub = this->create_publisher<Twist>("/cmd_vel", 10);
auto scan_sub_qos =
rclcpp::QoS(rclcpp::KeepLast(10), rmw_qos_profile_sensor_data);
rclcpp::SubscriptionOptions scan_sub_options;
scan_sub_options.callback_group =
create_callback_group(rclcpp::CallbackGroupType::Reentrant);
scan_sub = this->create_subscription<LaserScan>(
"/scan", scan_sub_qos,
std::bind(&MyRobot::scan_callback, this,
std::placeholders::_1),
scan_sub_options);
auto odom_sub_qos =
rclcpp::QoS(rclcpp::KeepLast(10), rmw_qos_profile_sensor_data);
rclcpp::SubscriptionOptions odom_sub_options;
odom_sub_options.callback_group =
create_callback_group(rclcpp::CallbackGroupType::Reentrant);
odom_sub = this->create_subscription<Odometry>(
"/odom", odom_sub_qos,
std::bind(&MyRobot::odom_callback, this,
std::placeholders::_1),
odom_sub_options);
timer_cbg = create_callback_group(rclcpp::CallbackGroupType::Reentrant);
timer = this->create_wall_timer(
std::chrono::milliseconds(1000),
std::bind(&MyRobot::movement_callback, this), timer_cbg);
// other statements
// 1. How to initialize Service Client here so it can be used in movement_callback() method below ?
// 2. How to initialize Action Client here so it can be used in movement_callback() method below ?
}
~MyRobot() {}
// other public methods
void scan_callback(const LaserScan::SharedPtr scan_msg) {
// statements
}
void odom_callback(const Odometry::SharedPtr odom_msg) {
// statements
}
void movement_callback() {
// service_client call_service() method is called here
// 3. How to use rclcpp::spin_some(service_client) here ?
// other statements for robot movement
// action_client send_goal() method is called here
// 4. How to use rclcpp::spin_some(action_client) here ?
// other statements for robot movement
};
int main(int argc, char *argv[]) {
rclcpp::init(argc, argv);
auto robot_node = std::make_shared<MyRobot>();
// 5. How to create service client node here ?
// the service client must be initialized inside MyRobot class
// 6. How to create action client node here ?
// the action client must be initialized inside MyRobot class
rclcpp::executors::MultiThreadedExecutor executor;
executor.add_node(robot_node);
executor.spin();
RCLCPP_INFO(robot_node->get_logger(), "Terminating...");
rclcpp::shutdown();
return 0;
}
// End of Code
Thanks in advance,
Girish