Hi,
I am working on part3 of the WallFollower project. While adding the Action Client to my main node, I am getting the following compilation error:
I tried to follow the instructions of the course, I don’t understand what could be the problem. My code related to the constructor and action client function is posted bellow:
class WallFollower : public rclcpp::Node
{
public:
using OdomRecord = custom_interfaces::action::OdomRecord;
using GoalHandleOdomRecord = rclcpp_action::ClientGoalHandle<OdomRecord>;
explicit WallFollower(const rclcpp::NodeOptions & node_options = rclcpp::NodeOptions())
: Node("wall_follower", node_options), goal_done_(false)
{
subscribers_callback_group =this->create_callback_group(rclcpp::CallbackGroupType::MutuallyExclusive);
publishers_callback_group =this->create_callback_group(rclcpp::CallbackGroupType::MutuallyExclusive);
action_client_callback_group =this->create_callback_group(rclcpp::CallbackGroupType::MutuallyExclusive);
rclcpp::SubscriptionOptions options1;
options1.callback_group = subscribers_callback_group;
vel_publisher = this->create_publisher<geometry_msgs::msg::Twist>("cmd_vel", 10);
odom_subscriber = this->create_subscription<nav_msgs::msg::Odometry>(
"odom", 10, std::bind(&WallFollower::odom_subs_callback, this, _7), options1);
scan_subscriber = this->create_subscription<sensor_msgs::msg::LaserScan>(
"scan", rclcpp::SensorDataQoS(), std::bind(&WallFollower::scan_subs_callback, this, _7), options1);
timer_ = this->create_wall_timer(500ms, std::bind(&WallFollower::robot_motion, this), publishers_callback_group);
print_timer = this->create_wall_timer(2000ms, std::bind(&WallFollower::print_function, this), publishers_callback_group);
this->client_ptr_ = rclcpp_action::create_client<OdomRecord>(
this->get_node_base_interface(),
this->get_node_graph_interface(),
this->get_node_logging_interface(),
this->get_node_waitables_interface(),
"record_odom");
this->action_client_timer_ = this->create_wall_timer(std::chrono::milliseconds(500), std::bind(&WallFollower::send_goal, this), action_client_callback_group);
this->rotation_z = 0.0;
this->distance_to_wall = 0.0;
this->distance_to_front_wall= 0.0;
this->offset_angle = 0.0;
this->linear_vel = 0.1;
this->angular_vel = 0.1;
this->dist_tol = 0.02;
this->angle_tol = 3.0*M_PI/180;
this->timer_period = 0.5;
}
bool is_goal_done() const
{
return this->goal_done_;
}
void send_goal()
{
using namespace std::placeholders;
this->action_client_timer_->cancel();
this->goal_done_ = false;
if (!this->client_ptr_) {
RCLCPP_ERROR(this->get_logger(), "Action client not initialized");
}
if (!this->client_ptr_->wait_for_action_server(std::chrono::seconds(10))) {
RCLCPP_ERROR(this->get_logger(), "Action server not available after waiting");
this->goal_done_ = true;
return;
}
auto goal_msg = OdomRecord::Goal();
RCLCPP_INFO(this->get_logger(), "Sending goal");
auto send_goal_options = rclcpp_action::Client<OdomRecord>::SendGoalOptions();
send_goal_options.goal_response_callback =
std::bind(&WallFollower::goal_response_callback, this, _1);
send_goal_options.feedback_callback =
std::bind(&WallFollower::feedback_callback, this, _1, _2);
send_goal_options.result_callback =
std::bind(&WallFollower::result_callback, this, _1);
auto goal_handle_future = this->client_ptr_->async_send_goal(goal_msg, send_goal_options);
}
void goal_response_callback(const GoalHandleOdomRecord::SharedPtr & goal_handle)
{
if (!goal_handle) {
RCLCPP_ERROR(this->get_logger(), "Goal was rejected by server");
} else {
RCLCPP_INFO(this->get_logger(), "Goal accepted by server, waiting for result");
}
}
void feedback_callback(
GoalHandleOdomRecord::SharedPtr,
const std::shared_ptr<const OdomRecord::Feedback> feedback)
{
RCLCPP_INFO(
this->get_logger(), "Feedback received: Total current distance = %f", feedback->current_total);
}
void result_callback(const GoalHandleOdomRecord::WrappedResult & result)
{
this->goal_done_ = true;
switch (result.code) {
case rclcpp_action::ResultCode::SUCCEEDED:
break;
case rclcpp_action::ResultCode::ABORTED:
RCLCPP_ERROR(this->get_logger(), "Goal was aborted");
return;
case rclcpp_action::ResultCode::CANCELED:
RCLCPP_ERROR(this->get_logger(), "Goal was canceled");
return;
default:
RCLCPP_ERROR(this->get_logger(), "Unknown result code");
return;
}
RCLCPP_INFO(this->get_logger(), "RESULT RECEIVED");
}