在您提供的 ControllerNode 类代码中,报错信息指出在创建 subscription 时存在运算符不匹配的问题。这主要是因为代码中存在语法错误,特别是在 create_subscription 方法的调用中缺少了必要的尖括号 < 和 > 来指定消息类型。此外,还有其他几处类似的语法错误需要修正。
以下是修改后的代码,包括修正语法错误和一些潜在的逻辑问题:
#include <rclcpp/rclcpp.hpp>
#include <geometry_msgs/msg/twist.hpp>
#include <turtlesim/msg/pose.hpp>
#include <turtlesim/srv/set_pen.hpp>
#include <turtlesim/srv/teleport_absolute.hpp>
#include <std_srvs/srv/empty.hpp>
#include <custom_interfaces/srv/trajectory.hpp>
#include <chrono>
class ControllerNode : public rclcpp::Node
{
public:
ControllerNode() : Node("controller")
{
subscription = this->create_subscription<turtlesim::msg::Pose>(
"/turtle1/pose", 10, std::bind(&ControllerNode::topic_callback, this, std::placeholders::_1));
publisher = this->create_publisher<geometry_msgs::msg::Twist>("/turtle1/cmd_vel", 10);
path_service_client = this->create_client<custom_interfaces::srv::Trajectory>("plan_path");
pen_service_client = this->create_client<turtlesim::srv::SetPen>("turtle1/set_pen");
teleport_service_client = this->create_client<turtlesim::srv::TeleportAbsolute>("turtle1/teleport_absolute");
clear_service_client = this->create_client<std_srvs::srv::Empty>("/clear");
timer = this->create_wall_timer(
10000ms, std::bind(&ControllerNode::timer_callback, this));
pose_msg = std::make_shared<turtlesim::msg::Pose>();
while (!path_service_client->wait_for_service(1s) ||
!pen_service_client->wait_for_service(1s) ||
!teleport_service_client->wait_for_service(1s)) {
if (!rclcpp::ok()) {
RCLCPP_ERROR(rclcpp::get_logger("rclcpp"), "Interrupted while waiting for the service. Exiting.");
return;
}
RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "Service not available, waiting again...");
}
auto pen_request = std::make_shared<turtlesim::srv::SetPen::Request>();
pen_request->r = 1;
pen_request->g = 1;
pen_request->b = 1;
pen_request->width = 1;
pen_request->off = false;
auto pen_response_callback = [this](rclcpp::Client<turtlesim::srv::SetPen>::SharedFuture future) {
RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "Succeeded to call service turtle1/set_pen");
auto response = future.get();
};
pen_service_client->async_send_request(pen_request, pen_response_callback);
}
private:
void timer_callback()
{
RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "Turtle at [x='%f', y='%f']", pose_msg->x, pose_msg->y);
auto path_request = std::make_shared<custom_interfaces::srv::Trajectory::Request>();
path_request->point.x = pose_msg->x;
path_request->point.y = pose_msg->y;
// Call service /clear
auto clear_request = std::make_shared<std_srvs::srv::Empty::Request>();
auto clear_response_callback = [this](rclcpp::Client<std_srvs::srv::Empty>::SharedFuture future) {
auto response = future.get();
};
clear_service_client->async_send_request(clear_request, clear_response_callback);
auto path_response_callback = [this](rclcpp::Client<custom_interfaces::srv::Trajectory>::SharedFuture future) {
RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "Succeeded to call service plan_path");
auto response = future.get();
for (const auto& point : response->trajectory_points) {
auto teleport_request = std::make_shared<turtlesim::srv::TeleportAbsolute::Request>();
teleport_request->x = point.x;
teleport_request->y = point.y;
teleport_request->theta = 0;
RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "Move to [x='%f', y='%f']", teleport_request->x, teleport_request->y);
auto teleport_response_callback = [this](rclcpp::Client<turtlesim::srv::TeleportAbsolute>::SharedFuture future) {
RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "Succeeded to call service turtle1/teleport_absolute");
auto response = future.get();
};
teleport_service_client->async_send_request(teleport_request, teleport_response_callback);
}
};
// Delay for 2 seconds (uncomment if needed)
// std::this_thread::sleep_for(std::chrono::seconds(2));
if (pose_msg->linear_velocity == 0 && pose_msg->angular_velocity == 0) {
path_service_client->async_send_request(path_request, path_response_callback);
}
}
void topic_callback(const turtlesim::msg::Pose& msg) const
{
*pose_msg = msg;
}
rclcpp::Subscription<turtlesim::msg::Pose>::SharedPtr subscription;
rclcpp::Publisher<geometry_msgs::msg::Twist>::SharedPtr publisher;
rclcpp::Client<custom_interfaces::srv::Trajectory>::SharedPtr path_service_client;
rclcpp::Client<turtlesim::srv::SetPen>::SharedPtr pen_service_client;
rclcpp::Client<turtlesim::srv::TeleportAbsolute>::SharedPtr teleport_service_client;
rclcpp::Client<std_srvs::srv::Empty>::SharedPtr clear_service_client;
rclcpp::TimerBase::SharedPtr timer;
std::shared_ptr<turtlesim::msg::Pose> pose_msg;
};
主要修正点:
尖括号 < > 的使用:在创建 subscription, publisher, client 时正确使用了尖括号来指定模板参数。
占位符 _1 的命名空间:使用 std::placeholders::_1 替代 _1,确保正确绑定回调函数的参数。
消息赋值:在 topic_callback 中使用 *pose_msg = msg; 替代逐字段赋值,以避免潜在的错误。
注释和代码格式:改善了代码的可读性,增加了必要的注释。
确保所有必要的头文件都已包含,并且 custom_interfaces::srv::Trajectory 是您项目中正确定义的服务。如果 custom_interfaces 不是标准 ROS 2 的一部分,请确保它已正确导入和编译。
以上为生成回答,仅供参考~