创新项目实战之智能跟随机器人原理与代码实现
目录
0 专栏介绍
本专栏旨在通过对ROS的系统学习,掌握ROS底层基本分布式原理,并具有机器人建模和应用ROS进行实际项目的开发和调试的工程能力。
🚀详情:《ROS从入门到精通》
1 智能跟随机器人的应用
机器人是传感器网络、通信、人工智能、分布式计算、自动化等多种技术的集大成者,机器人技术的发展水平标志着一个国家工业、制造业的先进性和创新性。
机器人产业市场潜力巨大,在工业机器人高端产业应用的背景下,服务机器人成为新的一片蓝海。
在众多机器人中,移动机器人的发展最为迅速,已经大规模落地商业化。智能跟随机器人是其中很常见的应用,在各类竞赛、创新项目、开源项目甚至商业项目中都有应用。例如以下场景:
- 高尔夫球场
- 病人看护
- 物流基地
- 商业导购
- 军事运输
- 2022 TI杯赛题
- …
本文基于ROS从入门到精通(十) TF坐标变换原理,为什么需要TF变换?中TF变换的原理,构造一个智能跟随机器人Demo,便于提供二次开发。总体的运行流程很简单:初始化两个机器人
->获取机器人1相对全局坐标系的坐标
->设置该坐标为机器人2的目标点
,其中第二步就用到了TF变换。虽然原理简单,但是可扩展性强。例如:
- 机器人1可以换成行人,在机器人2上应用激光的方法探测坐标
- 机器人1可以换成跟踪物体,在机器人2上应用视觉和图像处理的方法探测坐标
- 应用本文涉及的TF变换,设计多机器人作业环境
- …
为了便于扩展,本文采用规范工程化的编程方式。
2 构造机器人对象
由于实际场景中机器人的异构性,我们不能只设置若干函数来驱动机器人。对应地,我们采用面向对象思想,从通用机器人Robot
接口类中派生出各种不同的机器人类,比如本文设计的Turtle
机器人类如下:
class Turtle: public general_robot::Robot{ public: /** * @brief 机器人对象默认构造函数 **/ Turtle(); /** * @brief 机器人构造函数 * @param[in]: name -> 机器人名字 * @retval: None **/ Turtle(std::string name); /** * @brief 机器人对象默认析构函数 **/ ~Turtle();/** * @brief 初始化函数 * @param[in]: name -> 机器人名字 * @retval: None **/ void initialize(std::string name);/** * @brief 驱动机器人运动 * @param[in]: cmd -> 运动控制消息 * @retval: None **/ void driveRobot(geometry_msgs::Twist cmd);/** * @brief 设置机器人起始位姿 * @param[in]: pose -> 起始位姿 * @retval: None **/ void setStart(general_robot::Pose pose); /** * @brief 设置机器人起始位姿 * @param[in]: pose -> 起始位姿 * @retval: None **/ void setGoal(general_robot::Pose pose);}
这样设计的好处是在应用层接口可以统一起来,比如路径规划,我们只需要传入任意派生的机器人对象就可以实现多态,对不同结构、参数的机器人实现统一的规划算法。
3 机器人初始化
主要是位姿初始化,这里对于本地项目采用很简单的方式实现。对于CS架构,用户可以提交配置列表到后端服务器,服务器解析出位姿数据,再进行形如下面的初始化。为了避免业务逻辑混淆核心概念,本文就以下面的函数为例。
std::vector<turtle_robot::Turtle> robotInitialization(){ std::vector<turtle_robot::Turtle> robots; turtle_robot::Turtle robot1("robot1"); general_robot::Pose start; start.x = -2.0; start.y = -0.5; start.theta = PI / 2; robot1.setStart(start); robots.push_back(robot1); turtle_robot::Turtle robot2("robot2"); start.x = 2.0; start.y = 0.5; start.theta = PI / 2; robot2.setStart(start); robots.push_back(robot2); return robots;}
4 实现跟随
首先打开一个ros循环,实现持久性的跟随任务。
while (ros::ok()){ // 接下来介绍的逻辑在这里}
接着,获得机器人1相对地图的位姿
geometry_msgs::TransformStamped tfs = buffer.lookupTransform("map","robot1/base_footprint",ros::Time(0)); ROS_INFO("[x:%.2f, y:%.2f]", tfs.transform.translation.x, tfs.transform.translation.y);
将这个全局位姿作为机器人2的目标点
goal.x = tfs.transform.translation.x;goal.y = tfs.transform.translation.y;goal.theta = PI / 2;robots[1].setGoal(goal);
继续循环
loop_rate.sleep();ros::spinOnce();
5 效果展示
三维仿真场景如下所示:
完整代码联系下方博主名片获取
🔥 更多精彩专栏:
- 《ROS从入门到精通》
- 《机器人原理与技术》
- 《机器学习强基计划》
- 《计算机视觉教程》
- …
👇源码获取 · 技术交流 · 抱团学习 · 咨询分享 请联系👇