导航时通过程序发布目标点,实现循环导航

使用action通信方式,客户端提交目标点,服务端订阅处理,在客户端实时发布反馈位姿信息,具体通信原理可参考官网的action通信介绍。

服务端:

/*
      需求:软件实现一系列目标点的发送
                  1.包含头文件;
                  2.节点初始化;
                  3.创建NodeHandle;
                  4.创建action服务端对象;
                  5.处理请求,产生反馈与响应
                  6.回旋函数spin().
*/

这部分重点主要是订阅目标位姿,并发布出去。

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);
}

客户端:

/*
      需求:软件实现一系列目标点的发送
                  1.包含头文件;
                  2.节点初始化;
                  3.创建NodeHandle;
                  4.创建action客户端对象;
                  5.发送请求;
                        a.服务端与客户端建立连接;---回调函数
                        b.处理连续反馈;-----------------回调函数
                        c.处理最终响应。-----------------回调函数
                  6.回旋函数spin().
*/

//处理连续反馈

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);
}

 初始化位姿,发送目标点,并在回调函数中进行处理。

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();
           }
      }

此处粘贴部分程序,聪明的小伙伴根据我写的应该可以写出来了,要是想要完整的代码,我可就要不厚道的收费呀(http://t.csdn.cn/UUpbx)。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
以下是通过C++代码获取RVIZ中的publish point的目标点进行多点循环导航的示例代码: ``` #include <ros/ros.h> #include <geometry_msgs/PoseStamped.h> #include <vector> std::vector<geometry_msgs::PoseStamped> goals; void goalCallback(const geometry_msgs::PoseStamped::ConstPtr& msg) { ROS_INFO("Received a new goal position"); goals.push_back(*msg); } int main(int argc, char** argv) { ros::init(argc, argv, "multi_goal_navigation"); ros::NodeHandle nh; // Subscribe to the goal topic ros::Subscriber sub = nh.subscribe<geometry_msgs::PoseStamped>("move_base_simple/goal", 10, goalCallback); // Wait for the first goal to be received while (ros::ok() && goals.empty()) { ROS_INFO("Waiting for the first goal to be received..."); ros::spinOnce(); ros::Duration(1.0).sleep(); } // Start navigation to the first goal size_t i = 0; while (ros::ok()) { ROS_INFO("Starting navigation to goal %zu...", i+1); // Code to call the navigation stack to move to the current goal // If the navigation was successful, move to the next goal ++i; if (i >= goals.size()) { ROS_INFO("All goals have been reached, restarting navigation cycle..."); i = 0; } // Wait for the next goal to be received while (ros::ok() && goals.size() <= i) { ROS_INFO("Waiting for the next goal to be received..."); ros::spinOnce(); ros::Duration(1.0).sleep(); } } ROS_INFO("Navigation stopped."); return 0; } ``` 该代码与前面的示例代码类似,不同之处在于当所有的目标点都被导航到后,程序会重新从第一个目标点开始导航,并一直循环执行下去,直到程序被停止。在程序中,使用一个循环变量i来遍历所有的目标点,当i超过目标点的数量,将i重置为0,以实现循环导航的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值