步骤:
一. 安装ROS Kinetic
1)设置sources.list
sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
2)设置key
sudo apt-key adv --keyserver hkp://ha.pool.sks-keyservers.net:80 --recv-key 421C365BD9FF1F717815A3895523BAEEB01FA116
3)设置镜像(本地网速太慢)
sudo sh -c '. /etc/lsb-release && echo "deb http://mirrors.tuna.tsinghua.edu.cn/ros/ubuntu/ $DISTRIB_CODENAME main" > /etc/apt/sources.list.d/ros-latest.list'
4)安装kinetic
sudo apt-get update
sudo apt-get install ros-kinetic-desktop-full
5) 初始化依赖
sudo rosdep init
rosdep update
6)环境配置
echo "source /opt/ros/kinetic/setup.bash" >> ~/.bashrc
source ~/.bashrc
7)安装常用三方库
sudo apt install python-rosinstall python-rosinstall-generator python-wstool build-essential
二.创建工作区
$ mkdir -p ~/catkin_ws/src
$ cd ~/catkin_ws/
$ catkin_make
2)激活配置
$ source devel/setup.bash
或者永久激活该地址的配置文件:
echo "source /home/yourfile/devel / setup.bash" >> ~/.bashrc
三.构建自己的Catkin包
1)
cd ~/catkin_ws/src
2)使用catkin_create_pkg
命令来创建一个名为'beginner_tutorials'的新程序包,这个程序包依赖于std_msgs、roscpp和rospy
catkin_create_pkg beginner_tutorials std_msgs rospy roscpp
3)
roscd beginner_tutorials
四.定义自己的msg并编译:
1)
mkdir msg
cd msg
touch Num.msg
rosed beginner_tutorials Num.msg
2)定义msg类型(Num.msg文件,手工输入代码)
int64 num
3)打开文件rosed beginner_tutorials package.xml
,增加依赖
<build_depend>message_generation</build_depend>
<build_export_depend>message_runtime </build_export_depend>
<exec_depend>message_runtime</exec_depend>
4)打开文件rosed beginner_tutorials CMakeLists.txt
,增加依赖
将原find_package 修改为:
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
message_generation
)
5)增加消息文件,取消#,并修改为:
add_message_files(
FILES
Num.msg
)
6)增加消息生成包,取消#,并修改为:
generate_messages(
DEPENDENCIES
std_msgs
)
7)取消CATKIN_DEPENDS的#,并修改为:
catkin_package(
# INCLUDE_DIRS include
# LIBRARIES beginner_tutorials
CATKIN_DEPENDS roscpp rospy std_msgs message_runtime
# DEPENDS system_lib
)
8)编译:
$ cd ~/catkin_ws
$ catkin_make
9)测试:
rosmsg show beginner_tutorials/Num
结果:int64 num
五.编写发布器:
1)
roscd beginner_tutorials
2)建立脚本目录
mkdir scripts
cd scripts
3) 新建talk.py文件,并写推送消息文件
touch talker.py #生成文件
chmod +x talker.py #设置可执行
rosed beginner_tutorials talker.py #自己输入代码
4)编译
cd ~/catkin_ws
catkin_make
5)测试
启动新终端:
roscore
另一终端:
rosrun beginner_tutorials talker.py
六.订阅器同上
七.制作Launch文件
1)新建bringup目录
roscd beginner_tutorials
mkdir -p bringup
2)
cd bringup
rosed beginner_tutorials talker-and-listener.launch
3)手工输入代码
<launch>
<node name="talker" pkg="beginner_tutorials" type="talker.py" />
<node name="listener" pkg="beginner_tutorials" type="listener.py" />
</launch>
4)运行
roslaunch beginner_tutorials talker-and-listener.launch
第二部分:service部分
定义srv服务
- 在beginner_tutorials,新建srv服务目录,新建AddTwoInts.srv文件
$ roscd beginner_tutorials
$ mkdir srv
$ cd srv
$ touch AddTwoInts.srv
$ rosed beginner_tutorials AddTwoInts.srv
- srv文件分为请求和响应两部分,由'---'分隔。手工输入代码:
int64 A
int64 B
---
int64 Sum
- 打开文件
rosed beginner_tutorials package.xml
,增加依赖,
<build_depend>message_generation</build_depend>
<build_export_depend>message_runtime </build_export_depend>
<exec_depend>message_runtime</exec_depend>
- 打开文件
rosed beginner_tutorials CMakeLists.txt
,增加依赖,
# Do not just add this line to your CMakeLists.txt, modify the existing line
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
message_generation
)
- 在CMakeLists.txt文件,增加服务文件,取消#,并修改为
add_service_files(
FILES
AddTwoInts.srv
)
- 在CMakeLists.txt文件,增加消息生成包,取消#,并修改为
generate_messages(
DEPENDENCIES
std_msgs
)
- 编译代码
$ cd ~/catkin_ws
$ catkin_make
- 检查服务
- 命令:
$ rossrv show beginner_tutorials/AddTwoInts
- 效果:
int64 a
int64 b
---
int64 sum
编写服务端节点
roscd beginner_tutorials/scripts
$ touch add_two_ints_server.py
$ chmod +x add_two_ints_server.py
$ rosed beginner_tutorials add_two_ints_server.py
编写代码内容,后:
cd ~/catkin_ws/
$ catkin_make
- 测试代码
- 打开新终端,启动add_two_ints_server.py
$ rosrun beginner_tutorials add_two_ints_server.py
制作launch文件
- 进入bringup目录,新建server_client.launch,用来启动add_two_ints_server.py
$ roscd beginner_tutorials/bringup
$ touch server_client.launch
$ rosed beginner_tutorials server_client.launch
- 手工输入如下代码:
<launch>
<node name="server" pkg="beginner_tutorials" type="add_two_ints_server.py" />
</launch>
教程:https://www.ncnynl.com/archives/201611/1073.html
服务端和客户端代码解析:
服务端:
#!/usr/bin/env python
from beginner_tutorials.srv import *
import rospy
def handle_add_two_ints(req):
print "Returning [%s + %s = %s]"%(req.a, req.b, (req.a + req.b))
return AddTwoIntsResponse(req.a + req.b) #因为我们已经将服务的类型声明为AddTwoInts,所以它会为您生成AddTwoIntsRequest对象(可以自由传递)。
def add_two_ints_server():
rospy.init_node('add_two_ints_server') #声明节点为add_two_ints_server(Python文件名)
s = rospy.Service('add_two_ints', AddTwoInts, handle_add_two_ints) #服务实例化,给服务命名add_two_ints,服务类型为AddTwoInts,所有请求都传递给handle_add_two_ints函数。
print "Ready to add two ints."
rospy.spin() #此语句保证直到节点被关闭,代码才会停止运行
if __name__ == "__main__":
add_two_ints_server()
客户端:
#!/usr/bin/env python
import sys
import rospy
from beginner_tutorials.srv import *
def add_two_ints_client(x, y):
rospy.wait_for_service('add_two_ints') #在客户端中我们不需要创建node,这是一种便捷方法,可以阻止名为add_two_ints的服务可用。(即声明此为客户端)
try:
add_two_ints = rospy.ServiceProxy('add_two_ints', AddTwoInts) #调用服务,服务名为add_two_ints,类型AddTwoInts
resp1 = add_two_ints(x, y) #调用服务端函数,客户端传递参数x,y 让服务端进行处理。
return resp1.sum
except rospy.ServiceException, e: #如果调用失败,可能会抛出rospy.ServiceException
print "Service call failed: %s"%e
def usage():
return "%s [x y]"%sys.argv[0]
if __name__ == "__main__":
if len(sys.argv) == 3:
x = int(sys.argv[1])
y = int(sys.argv[2])
else:
print usage()
sys.exit(1)
print "Requesting %s+%s"%(x, y)
print "%s + %s = %s"%(x, y, add_two_ints_client(x, y))
rosrun beginner_tutorials add_two_ints_client.py 4 5
输出:
Requesting 4+5
4 + 5 = 9
运行服务器的终端输出:
Returning [4 + 5 = 9]
#!/usr/bin/python # -*- coding: utf-8 -*- import sys import time sys.setdefaultencoding('utf8') reload(sys) import os import simplejson as json from beginner_tutorials.srv import * import rospy #import time class detection(): def __init__(self): self.answer = {{"code": 200, "msg": "sucess", "data": {"datetime": "99999", "shelfId": "001", "row": 1, "col": 1, "sku": "123456789", "num": -2, "flag": 0, "weight": 1200} }} # def savetxt(self): # 将识别结果存储到txt文档中(时间戳+类别) # # File = open("E:\\1.txt", 'a+') # File.write('数据' + str(i) + '\n') # File.flush() # time.sleep(1) def findtxt(filename): #加载文档,进行时间戳匹配 ,进行200帧的缓存 try: filesize = os.path.getsize(filename) print filesize if filesize == 0: return None else: with open(filename, 'rb') as fp: offset = -2500 while -offset > filesize: time.sleep(1) findtxt(filename) #fp.seek(offset, 2) for lines in fp.readlines()[-200:]: if line.split()[0] == self.answer["data"]["datetime"]: self.answer["data"]["sku"] = line.split()[1] print line.split()[1] print lines except: print(filename + ' not found!') return None #检测结果 def detection_output(self,dict): text = json.loads(dict,encoding='utf-8') # 解码 print 'text',text try: self.answer["data"]["datetime"] = text["datetime"] self.answer["data"]["shelfId"] = text["shelfId"] self.answer["data"]["row"] = text["row"] self.answer["data"]["col"] = text["col"] self.answer["data"]["sku"] = text["sku"] self.answer["data"]["flag"] = text["flag"] self.answer["data"]["weight"] = text["weight"] self.answer["data"]["num"] = text["num"] #self.answer["data"]["sku"]=text["sku"] #从txt文档中读取商品名信息,进行时间戳匹配 filename='E:\\1.txt' self.findtxt(filename) except: self.answer["code"] =0 self.answer["msg"] = 'failure' return self.answer def data(dict): result = detection().detection_output(dict) print 'result',result result = json.dump(result) # 编码 return result def main(self): rospy.init_node(xmart) #Py文件名 rospy.loginfo('labeles recoder node is created!') rospy.Service('xmart', string, self.data) # 节点名称, 节点类型,处理的函数 服务命名 print "success" rospy.spin() if __name__ == "__main__": main()