ros 框架实现通讯的搭建心得

本文详细介绍了如何在ROS Kinetic中搭建通信框架,包括安装、工作区创建、Catkin包构建、msg定义与编译、发布器与订阅器的编写,以及服务(srv)的创建和使用。通过实例演示了AddTwoInts服务的服务器端和客户端代码,展示了如何通过launch文件启动服务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://wiki.ros.org   官网

步骤:

一.    安装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服务

  1. 在beginner_tutorials,新建srv服务目录,新建AddTwoInts.srv文件
$ roscd beginner_tutorials
$ mkdir srv
$ cd srv
$ touch AddTwoInts.srv
$ rosed beginner_tutorials AddTwoInts.srv
  1. srv文件分为请求和响应两部分,由'---'分隔。手工输入代码:
int64 A
int64 B
---
int64 Sum
  1. 打开文件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>
  1. 打开文件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
)
  1. 在CMakeLists.txt文件,增加服务文件,取消#,并修改为
add_service_files(
   FILES
   AddTwoInts.srv
 )
  1. 在CMakeLists.txt文件,增加消息生成包,取消#,并修改为
generate_messages(
  DEPENDENCIES
  std_msgs
)
  1. 编译代码
$ cd ~/catkin_ws
$ catkin_make
  1. 检查服务
  • 命令:
$ 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
  1. 测试代码
  • 打开新终端,启动add_two_ints_server.py
$ rosrun beginner_tutorials add_two_ints_server.py

制作launch文件

  1. 进入bringup目录,新建server_client.launch,用来启动add_two_ints_server.py
$ roscd beginner_tutorials/bringup
$ touch server_client.launch
$ rosed beginner_tutorials server_client.launch
  1. 手工输入如下代码:
<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()

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值