Usando el método de comunicación de acción, el cliente envía el punto de destino, el servidor se suscribe para el procesamiento y libera la información de la postura de retroalimentación en tiempo real en el cliente. Para conocer los principios de comunicación específicos, consulte la introducción de la comunicación de acción en el sitio web oficial.
Servidor:
/*
Requisito: El software realiza el envío de una serie de puntos de destino
1. Incluir el archivo de encabezado,
2. Inicialización del nodo,
3. Crear NodeHandle,
4. Crear el objeto del servidor de acción,
5. Procesar la solicitud, generar comentarios y respuesta
6. La función de giro girar ().
*/
El objetivo de esta parte es suscribirse a la pose de destino y publicarla.
void CallBack(const move_base_msgs::MoveBaseGoalConstPtr &goal,Movebase_Server *movebase_server)
{
move_base_msgs::MoveBaseGoal aim_goal;
aim_goal.target_pose.header.frame_id=goal->target_pose.header.frame_id;
aim_goal.target_pose.header.stamp=goal->target_pose.header.stamp;
aim_goal.target_pose.pose.position.x=goal->target_pose.pose.position.x;
aim_goal.target_pose.pose.position.y=goal->target_pose.pose.position.y;
aim_goal.target_pose.pose.position.z=goal->target_pose.pose.orientation.w;
ROS_INFO("提交的目标位姿为:x=%.2f,y=%.2f,w=%.2f",
aim_goal.target_pose.pose.position.x,
aim_goal.target_pose.pose.position.y,
aim_goal.target_pose.pose.orientation.w);
move_base_msgs::MoveBaseFeedback fb;
fb.base_position=aim_goal.target_pose;
movebase_server->publishFeedback(fb);
}
cliente:
/*
Requisito: El software realiza el envío de una serie de puntos de destino
1. Incluir archivos de encabezado,
2. Inicialización de nodo,
3. Crear NodeHandle,
4. Crear objeto de cliente de acción,
5. Enviar solicitud,
a. Establecer conexión entre el servidor y cliente; --- función de devolución de llamada
b. maneja la retroalimentación continua; ----------------- función de devolución de llamada
c. maneja la respuesta final. ----------------- función de devolución de llamada
6. función de giro giro().
*/
// manejar retroalimentación continua
void feedback_cb(const move_base_msgs::MoveBaseFeedbackConstPtr &feedback)
{
ROS_INFO("机器人当前位姿为:[x=%.2f,y=%.2f,w=%.2f]",
feedback->base_position.pose.position.x,
feedback->base_position.pose.position.y,
feedback->base_position.pose.orientation.w);
}
Inicialice la pose, envíe el punto de destino y procéselo en la función de devolución de llamada.
void done_cb(const actionlib::SimpleClientGoalState &state,
const move_base_msgs::MoveBaseResultConstPtr &result);//状态反馈
void active_cb();// 服务端与客户端建立连接
void feedback_cb(const move_base_msgs::MoveBaseFeedbackConstPtr &feedback);// 处理连续反馈
actionlib::SimpleActionClient<move_base_msgs::MoveBaseAction> MoveBase_Client(nh,"move_base",true);
// 等待服务端启动
// MoveBase_Client.waitForServer();
while(!MoveBase_Client.waitForServer(ros::Duration(5.0)))
{
ROS_INFO("Waiting for the move_base action server!");
}
// 5.发送请求;
// 定义坐标数据
int size_c=8;
double airfloat_coord[size_c][2]={
{0,0},{1,0},{2,0},{2,1},{2,2},{1,2},{0,2},{0,1}};
move_base_msgs::MoveBaseGoal goal;
goal.target_pose.header.frame_id="map";
goal.target_pose.header.stamp=ros::Time::now();
// 读取数组中的目标点位置数据
for (int pose_x = 0; pose_x <=size_c; pose_x++)
// for (int pose_x = 0; pose_x <=GoalNums; pose_x++)
{
for (int pose_y = 0; pose_y <2; pose_y++)
// for (int pose_y = 0; pose_y <=GoalNums; pose_y++)
{
goal.target_pose.pose.position.x=airfloat_coord[pose_x][0];
if (pose_y==1)
{
goal.target_pose.pose.position.y=airfloat_coord[pose_x][pose_y];
}
// goal.target_pose.pose.position.x=pose_x;
// goal.target_pose.pose.position.y=pose_y;
goal.target_pose.pose.orientation.w=1.0;
// goal.target_pose.pose.orientation.w=atan2(goal.target_pose.pose.position.y,goal.target_pose.pose.position.x) ;
/*
void sendGoal(const move_base_msgs::MoveBaseGoal &goal,
boost::function<void (const actionlib::SimpleClientGoalState &state, const move_base_msgs::MoveBaseResultConstPtr &result)> done_cb,
boost::function<void ()> active_cb,
boost::function<void (const move_base_msgs::MoveBaseFeedbackConstPtr &feedback)> feedback_cb)
*/
ROS_INFO("发送目标!");
MoveBase_Client.sendGoal(goal,&done_cb,&active_cb,&feedback_cb);
MoveBase_Client.waitForResult();
ros::Duration(1.0).sleep();
}
}
Pegue parte del programa aquí, los amigos inteligentes deberían poder escribirlo de acuerdo con lo que escribí, si desea el código completo, se lo cobraré sin amabilidad ( http://t.csdn.cn/UUpbx ).