转向电机控制代码中,补偿信息在循环中发布,转向完成信息在回调函数中发布
转动电机控制代码中,对转动电机的控制在转向完成的回调函数中实现
这就意味着如果一直没有 /cmd_vel
消息发布,那么就没有转动电机的控制,从而导致控制时的异常
简单的方法是上电时先启动手柄节点,轨迹跟踪时再关闭手柄节点,即由不同的节点发布 /cmd_vel
消息,后续再考虑优化
G29 的控制消息是间断的,即动一下发一下,不会像手柄那样连续发送,这样会导致两个问题:
因此考虑将 /joy 消息订阅后连续发送,代码如下
#include <ros/ros.h>
#include <sensor_msgs/Joy.h>
#include <mutex>
using namespace std;
ros::Publisher continuous_pub;
sensor_msgs::Joy steer_msg;
mutex mut;
const int axis_button_num = 20;
void joy_callback(const sensor_msgs::Joy::ConstPtr &msg)
{
steer_msg = *msg;
lock_guard<mutex> lck(mut);
continuous_pub.publish(steer_msg);
mut.unlock();
}
int main(int argc, char *argv[])
{
ros::init(argc, argv, "g29_continuous");
ros::NodeHandle nh;
memset(&steer_msg, 0, sizeof(steer_msg));
steer_msg.axes.resize(axis_button_num);
steer_msg.buttons.resize(axis_button_num);
continuous_pub = nh.advertise<sensor_msgs::Joy>("/g29_msg", 1);
ros::Subscriber joy_sub = nh.subscribe("/joy", 1, joy_callback);
ros::Rate loop(25);
while (ros::ok())
{
lock_guard<mutex> lck(mut);
continuous_pub.publish(steer_msg);
mut.unlock();
ros::spinOnce();
loop.sleep();
}
return 0;
}
有新的 sensor_msgs::Joy
就更新 steer_msg
,否则就发布之前的 msg
💡 注意 resize
键轴和按钮,否则 robot_steerpub
会因为越界访问而报段错误
远程控制的完整通信流程如下