没有机器人,如何学习ROS
最近新冠疫情又出现反复,不少同学返校受阻,好几个月时间没摸过实验室的机器人了,心中难免惆怅。这一次带大家体验一下,在没有实体机器人的情况下,怎么折腾一台听人使唤的虚拟机器人。
使用语音识别引擎,识别语音指令
(“Go to the kitchen”)
机器人按照语音指令,执行相应的任务
(自主导航到“kitchen”这个航点)
实验程序结构:
ROS Kinetic (Ubuntu 16.04)
cd ~/catkin_ws/src/ |
ROS Melodic (Ubuntu 18.04)
cd ~/catkin_ws/src/ |
[实验步骤]
1、首先,新建一个ROS源码包Package。
在Ubuntu里打开一个终端程序,输入如下指令:
cd catkin_ws/src/ |
按下回车之后,即可进入ROS工作空间,然后输入如下指令新建一个ROS源码包:
catkin_create_pkg sr_pkg roscpp std_msgs |
这条指令的具体含义是:
指令 |
含义 |
catkin_create_pkg |
创建ROS源码包(package)的指令 |
sr_pkg |
新建的ROS源码包命名 |
roscpp |
C++依赖项,本例程使用C++编写,所以需要这个依赖项 |
std_msgs |
标准消息依赖项,语音识别结果使用其中的String数据格式 |
按下回车键后,可以看到如下信息,表示新的ROS软件包创建成功。
在VSCode中,可以看到工作空间里多了一个sr_pkg文件夹,在其src子文件夹上右键点击鼠标,选择“New File”新建一个代码文件。
新建的代码文件,咱们为其命名为“sr_node.cpp”。
命名完毕后,在IDE的右侧可以开始编写sr_node.cpp的代码,其内容如下:
#include #include static ros::Publisher nav_pub; void SRCallback(const std_msgs::String::ConstPtr & msg) {ROS_WARN("[SRCallback] - %s", msg->data.c_str()); int nFindIndex = 0; nFindIndex = msg->data.find("kitchen"); if (nFindIndex >= 0) { std_msgs::String nav_msg; nav_msg.data = "kitchen"; nav_pub.publish(nav_msg); } int main(intargc, char** argv) ros::init(argc, argv, "demo_sr_navigation"); ros::NodeHandle n; nav_pub = n.advertise("/waterplus/navi_waypoint", 10); ros::Subscriber sr_sub = n.subscribe("/xfyun/iat", 10, SRCallback); ros::spin(); return 0; |
(1)代码的开头include了两个头文件:ros.h是ros的系统头文件;String.h是字符串类型头文件,程序中语音识别结果需要用到这个字符串格式。
(2)程序开头定义了一个nav_pub对象,这个是导航目标的消息发布者。
(3)接下来定义一个回调函数void SRCallback(),用来处理xfyun_waterplus节点发来的语音识别结果消息包。
(4)回调函数void SRCallback()的参数msg是一个std_msgs::String格式指针,其指向的内存区域就是存放语音识别结果的内存空间。msg包里包含了一个data成员,这是一个String格式的对象,里面装载的就是语音识别结果字符串。咱们使用ROS_WARN将这个字符串内容显示在终端程序窗口里。
(5)使用msg->data字符串的函数find()在语音识别结果里搜索“kitchen”这个关键词,如果该函数返回值大于0,说明识别结果里包含这个关键词。咱们将目标航点“kitchen”通过nav_pub发布给导航插件,执行导航任务。
(6)在主函数main()中,调用ros::init(),对这个节点进行初始化。
(7)定义一个ros::NodeHandle节点句柄n,并使用这个句柄向ROS核心节点发布一个std_msgs::String类型的主题,主题名为“/waterplus/navi_waypoint”,负责导航的地图插件会从这个主题里读取咱们发送的目标航点名称并执行导航任务。接下来订阅Topic主题“/xfyun/iat”,回调函数设置为之前定义的SRCallback()。这个“/xfyun/iat”是xfyun_waterplus进行语音识别后发布结果的主题名,咱们自己写的这个节点sr_node只需要订阅它就能收到最终的语音识别结果。
(8)调用ros::spin()对main()函数进行阻塞,保持这个节点程序在接收到语音识别结果前不会结束退出。
代码编写完毕后,需要按下键盘快捷键Ctrl+S进行保存,代码上方的文件名右侧的小白点会变成“×”,说明保存文件成功。
接下来,还需要将节点源码文件添加到编译文件里才能进行编译。编译文件在sr_pkg的目录下,文件名为“CMakeLists.txt”,在VSCode界面左侧点击该文件,右侧会显示文件内容。在 “CMakeLists.txt”文件末尾,为obj_node.cpp添加新的编译规则。内容如下:
add_executable(sr_node src/sr_node.cpp ) add_dependencies(sr_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) target_link_libraries(sr_node ${catkin_LIBRARIES} ) |
同样,修改完需要按下键盘快捷键Ctrl+S进行保存,代码上方的文件名右侧的小白点会变成“×”,说明保存文件成功。下面开始进行代码文件的编译操作,启动一个终端程序,键入如下命令进入ROS的工作空间:
cd catkin_ws/ |
然后再执行如下命令开始编译:
catkin_make |
执行这条指令之后,会出现滚动的编译信息,直到出现“[100%] Built target sr_node”信息,说明新的sr_node节点已经编译成功。
2、下面咱们需要启动运行这个sr_node节点的虚拟仿真环境,具体步骤可以参看之前的实验:
《waterplus_map_tools开源的地图导航插件实验》
按照其中的实验步骤完成三个任务:
通过SLAM构建环境地图。
设置好包括“kitchen”在内的多个航点。
启动地图插件,设置好机器人的初始位置。
3、运行我们编写的sr_node节点,让其与地图导航插件完成连接,并开始监听语音识别结果。打开一个新的终端程序,输入以下指令:
rosrun sr_pkg sr_node |
回车执行,sr_node节点就启动起来了。
4、最后启动语音识别节点,由于语音识别功能使用的是科大讯飞的云服务,所以需要电脑连接到互联网,以便其与讯飞的云服务器建立数据连接。确认已经连接互联网后,打开一个新的终端程序,输入以下指令:
roslaunch xfyun_waterplus iat_en.launch |
回车执行,科大讯飞的语音识别引擎便开始启动。此时可以听到电脑有节奏的发出“嘟~”的提示音,这是语音识别开始的信号。我们需要在两次“嘟”的提示音之间将要识别的话说给机器人听,它才能够正确的识别。在“嘟”的一声之后对电脑麦克风说“Go to the kitchen”,电脑识别完毕后,会将识别结果显示在终端程序里。
这时查看运行sr_node的终端,可以看到回调函数接收到的语音识别结果。
再切换到Rviz和Gazebo仿真环境,可以看到机器人开始自主导航到“kitchen”航点。
[扩展练习]
实验中的语音识别引擎还能识别中文指令,只是启动指令需要换成:
roslaunch xfyun_waterplus iat_cn.launch |
节点sr_node的代码同学们可以尝试进行相应的修改,最后别忘了caktin_make编译再运行。
更多产品了解
欢迎扫码加入云巴巴企业数字化交流服务群
产品交流、问题咨询、专业测评
都在这里!
1月16日,2025腾讯产业合作伙伴大会在三亚召开。云巴巴,荣膺“2024腾讯云卓越合作伙伴奖—星云奖”和“2024腾讯云AI产品突出贡献奖”双项大奖
Testin云测自动化测试解决方案,以零代码降低门槛、全栈兼容打破生态壁垒、云端集约提升资源效能,助力企业跨越测试鸿沟,赢在数智化时代。
如何构建安全合规、敏捷高效的研发管理体系,已成为金融业高质量发展的关键命题。
腾讯TAPD正在凭借着三大亮点帮助众多互联网企业打破传统管理模式的束缚,实现更加透明、高效的协作。
云巴巴基于多年行业深耕,为大家推荐洞隐科技的智能航运管理平台,为企业开启“智慧航海”新篇章——这不仅是技术的升级,更是一场管理模式的革新。