在您提供的 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 的一部分,请确保它已正确导入和编译。
以上为生成回答,仅供参考~