ROSNOTE : 用代码控制机器人移动到目标点

(1) 代码的开始部分,先include了三个头文件,第一个是ros的系统头文件,第二个是导航目标结构体move_base_msgs::MoveBaseGoal的定义文件,第三个是actionlib::SimpleActionClient的定义文件。

(2) ROS节点的主体函数是int main(int argc, char** argv),其参数定义和其他C++程序一样。

(3) main函数里,首先调用ros::init(argc, argv, "demo_simple_goal");进行该节点的初始化操作,函数的第三个参数是节点名称。

(4) 接下来声明一个MoveBaseClient对象ac,用来调用和主管监控导航功能的服务。

(5) 在请求导航服务前,需要确认导航服务已经开启,所以这里调用ac.waitForServer()函数来查询导航服务的状态。ros::Duration()是睡眠函数,参数的单位为秒,表示睡眠一段时间,这段时间若被某个信号打断(在这个例程里,这个信号就是导航服务已经启动的信号),则中断睡眠。所以ac.waitForServer(ros::Duration(5.0));的意思就是:休眠5秒,若期间导航服务启动了,则中断睡眠,开始后面的操作。用while循环来嵌套,可以让程序在休眠5秒后,若导航服务未启动,则继续进入下一个5秒睡眠,直到导航服务启动才中断睡眠。

(6) 确认导航服务启动后,我们声明一个move_base_msgs::MoveBaseGoal类型结构体对象goal,用来传递我们要导航去的目标信息。
goal.target_pose.header.frame_id表示这个目标位置的坐标是基于哪个坐标系,例程里赋值“map”表示这是一个基于全局地图的导航目标位置。
goal.target_pose.header.stamp赋值当前时间戳。
goal.target_pose.pose.position.x 赋值-3.0,表示本次导航的目的地是以地图坐标系为基础,向X轴反方向移动3.0米。
goal.target_pose.pose.position的y赋值2.0,表示本次导航的目的地是以地图坐标系为基础,向Y轴正方向移动2.0米。
goal.target_pose.pose.position的z未赋值,则默认是0;
goal.target_pose.pose.orientation.w 赋值1.0,则导航的目标姿态是机器人面朝X轴的正方向(正前方)。

(7) ac.sendGoal(goal);将导航目标信息传递给导航服务的客户端ac,由ac来监控后面的导航过程。

(8) ac.waitForResult();等待MoveBase的导航结果,这个函数会保持阻塞,就是卡在这,直到整个导航过程结束,或者导航过程被其他原因中断。

(9) ac.waitForResult()阻塞结束后,调用ac.getState()获取导航服务的结果,如果是“SUCCEEDED”说明导航顺利到达目的地,输出结果“Mission complete!”;若不是这个结果,输出结果“Mission failed ...”。

 

/*********************************************************************
* Software License Agreement (BSD License)
* 
*  Copyright (c) 2017-2020, Waterplus http://www.6-robot.com
*  All rights reserved.
* 
*  Redistribution and use in source and binary forms, with or without
*  modification, are permitted provided that the following conditions
*  are met:
* 
*   * Redistributions of source code must retain the above copyright
*     notice, this list of conditions and the following disclaimer.
*   * Redistributions in binary form must reproduce the above
*     copyright notice, this list of conditions and the following
*     disclaimer in the documentation and/or other materials provided
*     with the distribution.
*   * Neither the name of the WaterPlus nor the names of its
*     contributors may be used to endorse or promote products derived
*     from this software without specific prior written permission.
* 
*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
*  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
*  FOOTPRINTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
*  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
*  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
*  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
*  POSSIBILITY OF SUCH DAMAGE.
*********************************************************************/

#include <ros/ros.h>
#include <move_base_msgs/MoveBaseAction.h>
#include <actionlib/client/simple_action_client.h>

typedef actionlib::SimpleActionClient<move_base_msgs::MoveBaseAction> MoveBaseClient;

int main(int argc, char** argv)
{
  ros::init(argc, argv, "demo_simple_goal");

  //tell the action client that we want to spin a thread by default
  //声明一个MoveBaseClient对象ac,用来调用和主管监控导航功能的服务。
  MoveBaseClient ac("move_base", true);

  //wait for the action server to come up(确定导航服务开启)
  while(!ac.waitForServer(ros::Duration(5.0)))
  {
    ROS_INFO("Waiting for the move_base action server to come up");
  }

  //用来传递我们导航去的目标信息
  move_base_msgs::MoveBaseGoal goal;

  goal.target_pose.header.frame_id = "map";
  goal.target_pose.header.stamp = ros::Time::now();

  goal.target_pose.pose.position.x = -3.0;
  goal.target_pose.pose.position.y = 2.0;
  goal.target_pose.pose.orientation.w = 1.0;

  ROS_INFO("Sending goal");
  //将导航目标信息传递给导航服务的客户端ac,由ac来监控后面的导航过程。
  ac.sendGoal(goal);

  ac.waitForResult();

  if(ac.getState() == actionlib::SimpleClientGoalState::SUCCEEDED)
    ROS_INFO("Mission complete!");
  else
    ROS_INFO("Mission failed ...");

  return 0;
}

 

  • 4
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
移动机器人控制代码可以根据不同的机器人和运动控制器而异,但是一般都包括以下几个步骤: 1. 读取当前机器人的位置和目标位置; 2. 计算机器人需要移动的距离和方向; 3. 发送运动控制指令,使机器人目标位置移动; 4. 循环执行步骤1-3,直到机器人到达目标位置。 以下是一个简单的示例代码,用于控制一个基于ROS移动机器人向指定的目标位置移动(假设机器人已经连接到ROS系统,并且已经安装了必要的软件包): ```python #!/usr/bin/env python import rospy from geometry_msgs.msg import Twist from nav_msgs.msg import Odometry # 定义当前机器人的位置和目标位置 current_pos = Odometry() target_pos = Odometry() # 订阅当前机器人的位置信息 def odom_callback(data): global current_pos current_pos = data rospy.init_node('move_robot', anonymous=True) # 订阅机器人的odom话题,获取机器人当前的位置信息 rospy.Subscriber('/odom', Odometry, odom_callback) # 发布机器人的运动控制指令 pub = rospy.Publisher('/cmd_vel', Twist, queue_size=10) # 设置机器人目标位置 target_pos.pose.pose.position.x = 1.0 target_pos.pose.pose.position.y = 1.0 rate = rospy.Rate(10) # 10hz while not rospy.is_shutdown(): # 计算机器人需要移动的距离和方向 dx = target_pos.pose.pose.position.x - current_pos.pose.pose.position.x dy = target_pos.pose.pose.position.y - current_pos.pose.pose.position.y distance = math.sqrt(dx*dx + dy*dy) angle = math.atan2(dy, dx) # 发送控制指令,使机器人目标位置移动 twist = Twist() twist.linear.x = 0.5 * distance # 假设机器人的最大线速度为0.5m/s twist.angular.z = 1.0 * angle # 假设机器人的最大角速度为1.0rad/s pub.publish(twist) # 到达目标位置后停止移动 if distance < 0.1: twist.linear.x = 0.0 twist.angular.z = 0.0 pub.publish(twist) break rate.sleep() ``` 这段代码中,我们使用了ROS的通信机制,订阅了机器人的odom话题,获取机器人当前的位置信息;同时,我们也发布了机器人的运动控制指令,使机器人目标位置移动。在每次循环中,我们都计算机器人需要移动的距离和方向,然后根据机器人的最大线速度和角速度,计算出机器人的运动控制指令并发送给机器人。当机器人到达目标位置后,我们停止机器人的运动,并退出程序。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值