北邮机器人队2020预备队培训(四) —— ROS基础二

前言

上一节讲了ros机制中的话题机制,今天教程讲剩余的两种机制,动作和服务.

ROS机制之服务

服务适用于只需要偶尔去做并且会在有限的时间内完成的事情.

举个例子,我们使用手机的时候想查询自己的手机话费余额,那我们可以使用10086的短信服务,只需要编辑短信发送给10086请求查询余额的服务我们就能收到查询结果.

测试ROS服务

这里使用ros入门例子测试服务机制.
首先启动ros:

roscore

打开小乌龟:

rosrun turtlesim turtlesim_node

启动键盘控制:

rosrun turtlesim turtle_teleop_key

北邮机器人队2020预备队培训(四) —— ROS基础二_第1张图片

查看服务列表:

rosservice list

调用清除轨迹的服务:

rosservice call clear

北邮机器人队2020预备队培训(四) —— ROS基础二_第2张图片

实现自己的服务

计算字符串中单词数目,例如输入:“one two three”,输出3

实现过程

1、创建服务WordCount.srv

1.1、进入basic包:

cd ~/catkin_ws/src/basic/

1.2、创建srv目录

mkdir srv

1.3、在srv目录下创建WordCount.srv文件

cd srv
vi WordCount.srv

1.4、输入如下内容:
北邮机器人队2020预备队培训(四) —— ROS基础二_第3张图片

2、修改CMakeLists.txt

cd ..
vi CMakeLists.txt

2.1、修改CMakeLists.txt的find_package()如下:
北邮机器人队2020预备队培训(四) —— ROS基础二_第4张图片
2.2、修改add_service_files()去掉注释加入WordCount.srv
如下图:
北邮机器人队2020预备队培训(四) —— ROS基础二_第5张图片
2.3、修改generate_messages()如下图:
在这里插入图片描述

3、修改package.xml文件加入message_generation和message_runtime如下图:

vi package.xml

在这里插入图片描述

4、返回catkin根目录编译:

cd ~/catkin_ws
catkin_make

5、编译成功后测试是否有这个服务了:

rossrv show WordCount

北邮机器人队2020预备队培训(四) —— ROS基础二_第6张图片

6、实现服务:

6.1、在basic包的src文件夹下创建service_server.py文件,设置权限:

cd ~/catkin_ws/src/basic/src
vi service_server.py
chmod 777 service_server.py

service_server.py

#!/usr/bin/env python

import rospy

from basic.srv import WordCount,WordCountResponse

def count_words(request):
	return WordCountResponse(len(request.words.split()))

rospy.init_node('service_server')

service = rospy.Service('word_count',WordCount,count_words)

rospy.spin()

7、打开新终端运行roscore:

roscore

8、在原来的终端返回catkin的根目录编译:

cd ~/catkin_ws
catkin_make
source devel/setup.bash
rosrun basic service_server.py

在这里插入图片描述这是已经在运行了不过没写现象。

9、用ros的服务包里面的list检查服务是否可见(打开新终端):

rosservice list

北邮机器人队2020预备队培训(四) —— ROS基础二_第7张图片
可以看到word_count已经在服务了。

10、用ros服务包的info来看更多信息:

rosservice info word_count

在这里插入图片描述
他告诉了我们四项参数:

  • Node:当前提供服务的节点名字。
  • URL:服务的端口号
  • Type:服务的类型
  • Args:参数

11、直接命令调用使用服务

rosservice call word_count 'one two three'

在这里插入图片描述

12、代码方式使用服务

12.1、在basic的src内创建service_client.py文件:

cd ~/catkin_ws/src/basic/src
vi service_client.py
chmod 777 service_client.py

service_client.py:

#!/usr/bin/env python

import rospy

from basic.srv import WordCount

import sys

rospy.init_node('service_client')

rospy.wait_for_service('word_count')

word_counter=rospy.ServiceProxy('word_count',WordCount)

words=' '.join(sys.argv[1:])

word_count=word_counter(words)

print words,'->',word_count.count

12.2、返回catkin根目录编译运行

cd ~/catkin_ws
catkin_make
source devel/setup.bash
rosrun basic service_client.py one two three

在这里插入图片描述

ROS机制之动作

前面尝试了定义自己的消息类型和服务,接下来是定义动作。服务只适用于及时响应的消息类型,和编程的函数基本类似,有自己的输入输出。但是在解决机器人运作问题上服务显然就不够用了,就好比投篮,我们用服务来写只能做到写好一个服务将球投出去,至于球在空中的轨迹,是否进球框就不得而知了。而动作的话可以做到将球投出去,等待球进框或者没进框又做下一步的决策。

这里我们将创建一个计时的动作

实现过程

前面的步骤默认已经创建好了ros的工作区和创建好了包basic,在这基础上继续完成动作的创建。
1、ctrl+alt+t呼出终端,在basic目录下创建action目录,并在action目录下创建Timer.action文件:

cd ~/catkin_ws/src/basic/
mkdir action
cd action
vi Timer.action

输入如下文本在Timer.action中:

#这坑爹的书把变量全写在注释里了,还好我眼睛比较尖锐。。。坑死我了
#就像这样duration time_to_wait
#你如果中英文隔开我还挺好看出来的,妈妈的全是英文的谁会注意看哦
duration time_to_wait

---
duration time_elapsed
uint32 updates_sent


---
duration time_elapsed
duration time_remaining

这时可以看看文件目录关系:
北邮机器人队2020预备队培训(四) —— ROS基础二_第8张图片
2、运行catkin_make

cd ~/catkin_ws
catkin_make

3、修改CMakeLists.txt

cd ~/catkin_ws/src/basic
vi CMakeLists.txt

3.1、修改find_package()添加action_msgs:
北邮机器人队2020预备队培训(四) —— ROS基础二_第9张图片
3.2、修改add_action_files()中添加FILES Timer.action:北邮机器人队2020预备队培训(四) —— ROS基础二_第10张图片
3.3、修改generate_message()添加actionlib_msgs:北邮机器人队2020预备队培训(四) —— ROS基础二_第11张图片
3.4、修改catkin_package()添加actionlib_msgs:
北邮机器人队2020预备队培训(四) —— ROS基础二_第12张图片
4、在package.xml中加上构建依赖项和运行依赖项:

vi package.xml

粘贴下面两行进去。
actionlib_msgs
actionlib_msgs
北邮机器人队2020预备队培训(四) —— ROS基础二_第13张图片

5、返回catkin的根目录编译:

cd ~/catkin_ws/
catkin_make

6、编写基本动作服务器:
6.1、在basic包的src下创建simple_action_serve.py文件:

cd ~/catkin_ws/src/basic/src
vi simple_action_serve.py
chmod 777 simple_action_serve.py

输入以下;
simple_action_serve.py

#!/usr/bin/env python

import rospy
import time
import actionlib
from basic.msg import TimerAction,TimerGoal,TimerResult

def do_timer(goal):
	start_time=time.time()
	time.sleep(goal.time_to_wait.to_sec())
	result=TimerResult()
	result.time_elapsed=rospy.Duration.from_sec(time.time()-start_time)
	result.updates_sent=0
	server.set_succeeded(result)

rospy.init_node('timer_action_server')
server=actionlib.SimpleActionServer('timer',TimerAction,do_timer,False)
server.start()
rospy.spin()

6.2、ctrl+alt+t打开新终端运行roscore:

roscore

6.3、返回根目录编译运行脚本:

cd ~/catkin_ws
catkin_make
source devel/setup.bash
rosrun basic simple_action_serve.py

7、list看是否有相应的服务运行
北邮机器人队2020预备队培训(四) —— ROS基础二_第14张图片
8、动作的使用:
8.1、创建动作使用脚本:

cd ~/catkin_ws/src/basic/src
vi simple_action_client.py
chmod 777 simple_action_client.py

输入以下:
simple_action_client.py

#!/usr/bin/env python

import rospy
import actionlib
from basic.msg import TimerAction,TimerGoal,TimerResult

rospy.init_node('timer_action_client')
client=actionlib.SimpleActionClient('timer',TimerAction)
client.wait_for_server()
goal=TimerGoal()
goal.time_to_wait=rospy.Duration.from_sec(5.0)
client.send_goal(goal)
client.wait_for_result()
print('Time elapsed:%f'%(client.get_result().time_elapsed.to_sec()))

8.2、返回根目录编译运行脚本:

cd ~/catkin_ws
catkin_make
source devel/setup.bash
rosrun basic simple_action_client.py

运行效果:
在这里插入图片描述

作业

1.使用Python或者c语言实现有限状态机,可以通过终端输入来作为状态切换的标志.
2.完成本节实验,定义自己的服务和动作,随意发挥,但不要和本文例子相同.

作业提交

程序作业提交截至日期为2020年08月03日23时59分,上传到群文件夹7.31程序作业中,程序作业需要提交源代码,截图运行结果,写上必要的文字说明。

你可能感兴趣的:(北邮机器人队培训,python)