ros+modelarts实现多车辆协作

系列文章目录

第一章 华为云modelarts平台使用
第二章 华为云modelarts平台SDK的调用
第三章 ros+modelarts实现多车辆协作

前言

趁着寒假有空整理一下以前学习ros操作系统相关的东西。这篇博客并不适合对ros一点也不懂初学者,建议初学者去看bilibili ros有关的视频然后结合博客去看。如果仅仅想用modelarts识别不需要多协作可以不用看着篇文章。


一、ros简介及安装

ROS (Robot Operating System, 机器人操作系统) 提供一系列程序库和工具以帮助软件开发者创建机器人应用软件。它提供了硬件抽象、设备驱动、库函数、可视化、消息传递和软件包管理等诸多功能。ROS遵守BSD开源许可协议。

我用的jetson nano和tx2的ubuntu版本是18.04,ros版本应该用melodic。
以下安装的ros是完整版的,包含gazebo,如果内存小建议安装精简版的,到时候需要哪些软件包再安装哪些软件包就行。

sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654
sudo apt update
sudo apt install ros-melodic-desktop-full
sudo rosdep init
rosdep update
echo "source /opt/ros/melodic/setup.bash" >> ~/.bashrc
source ~/.bashrc
sudo apt install python-rosinstall python-rosinstall-generator python-wstool build-essential

安装完后可采用以下程序进行测试

roscore
rosrun turtlesim turtlesim_node
rosrun turtlesim turtle_teleop_key

sudo rosdep init
rosdep update
这两项安装时会报错可以忽略不用管。

二、工作空间和功能包的创建

同一空间下不能出现同名功能包
scr 代码空间

build 编译空间

devel 开发空间

install 安装空间

创建工作空间

$mkdir -p ~/catkin_ws/src
$cd ~/catkin_ws/src
$catkin_init_workspace

编译工作空间

$cd ~/catkin_ws
$catkin_make

设置环境变量

$source devel/setup.bash

检查环境变量

$echo $ROS_PACKAGE_PATH

创建功能包

$cd ~/catkin_ws/src
$catkin_create_pkg+创建文件的名字(pkg_name)+std_msgs roscpp rospy 。。。(依赖包)
将代码放进~/catkin_ws/src/上面创建的文件名称(pkg_name)/src

编译功能包

$cd ~/catkin_ws
$catkin_make
$source ~/catkin_ws/devel/setup.bash

三、ros的一些基本的操作

roscore

rosnode list 查看节点

rosnode info 查看节点信息

rostopic list 查看话题

rostopic pub 话题 tab键 发布指令

rosmsg show 话题 话题结构体

rosservice list 服务列表

rqt_graph 以图的形式显示关系

###################################################
rostopic list 查看所有话题

rostopic info 话题 查看话题的类型及信息

rosmsg info 数据类型 查看数据结构体
###################################################
rosservice list 列出所有活动的服务

rosservice type 服务 查看某个服务的类型

rosservice type 服务| rossrv show 查看某个服务类型具体输入什么类型的参数,返回什么类型的参数
###################################################

四、TF树的学习例程

小海龟跟随

sudo apt-get install ros-melodic-turtle-tf
roslaunch turtle_tf turtle_tf_demo.launch
rosrun turtlesim turtle_teleop_key 

rosrun turtlesim turtle_teleop_key   查看tf树,会在当前目录下生成一个pdf文件
rosrun tf tf_echo turtle1 turtle2    查看坐标等数
rosrun rviz rviz -d 'rospack find turtle_tf'/rviz/turtle_rviz.rviz   通过rviz查看坐标  需要将fixed改为world 然后add TF

五、ROS 多机通信(重要)


 一、ROS分布式多机通讯简介
ROS是一种分布式软件框架,节点之间通过松耦合的方式组合,在很多应用场景下,节点可以运行在不同的计算平台上,通过Topic,Service通信。
但是各个节点只能共同拥有一个Master,在多机系统中Master只能运行在一台机器上,其他机器通过ssh方式和Master取得联系。所以多机ROS系统需要进行一些配置。

二、两台电脑的ROS通讯配置
两台机器的hostname与IP假设如下:
主机名与IP地址为:A     IP_A        
从机名与IP地址为:B    IP_B
1:先使用下面命令查看两台计算机的局域网IP地址
ifconfig 
然后打开hosts文件:
sudo gedit /etc/hosts
接着在hosts中加入(间隔为tab键):
IP_A  A
IP_B  B
2:重启网络服务:
sudo /etc/init.d/networking restart
3:装上chrony包,用于实现同步:
sudo apt-get install chrony
4:安装ssh工具
sudo apt-get install openssh-server
安装完以后,确认服务器是否已经启动:
ps -e|grep ssh
如果看到sshd那说明ssh-server已经启动了。
5:相互ping一下对方机子,看网络通不通:
ping A     //主机
pnig B     //从机
对主机与从机相同地执行上述操作,第六条略有不同
6:把下面的内容增加到.bashrc末尾
export ROS_HOSTNAME=[本机的hostname] #!!!注意是本机的hostname 端口号11311是固定值,照抄即可
export ROS_MASTER_URI=http://[主机的hostname]:11311
执行以下命令,使之有效:
source ~/.bashrc

三、注意事项
如果在从机运行一个roslaunch,需要现在主机上运行roscore后,从机才能启动起来。
原本一个pc上运行roslaunch的时候,会默认启动rosmaster,但是现在主机是另一个pc了,所以需要这样先把master跑起来
尽量把最常用的pc设置为master。
电脑A端:

首先启动 ROS:
$ roscore
然后 Ctrl + T 打开新的控制台,运行:
$ rosrun turtlesim turtlesim_node
电脑B端:
$ rosrun turtlesim turtle_teleop_key

六、ros+modelarts实现多车辆协作

项目描述:

车a进行巡逻,通过摄像头采集数据,当发现病虫害时发消息给车b,车b接到消息后前往进行消毒。

涉及到的ros知识主要有ROS 多机通信和编写Publisher和Subscriber(Python版)。
Publisher和Subscriber的编写方法可以参考这篇博客:https://blog.csdn.net/zong596568821xp/article/details/78088394

难点一

环境配置,ros默认的python版本是2.7,但是jetbot驱动程序是python3.6,需要将ros默认的python版本改成3.6。

难点二

前面有提到过,python数据解析。

难点三

多机通信环境的配置。

a车程序:

方案一: 一边用摄像头识别一边将图片传至modelarts平台进行识别
出现的问题: 因为python不支持多线程(我尝试过python多线程并不好用和没有一样)而且modelarts平台识别速度较慢导致摄像头画面黑屏。
解决方法: 一个python程序进行图像采集,每隔一段时间将图片保存到一个固定地址。另一个python程序读取图片并传至华为云进行识别。当识别为病虫害时发送消息给b车。

图片采集

import cv2
cap = cv2.VideoCapture(1)    #打开摄像头
i=100
while(1):
  # get a frame
  ret, frame = cap.read()
  # show a frame
  cv2.imshow("capture", frame)   #生成摄像头窗口
  if i%100==0:
    cv2.imwrite("/home/nvidia/Desktop/1.jpg", frame)  #保存路径
  if cv2.waitKey(1) & 0xFF == ord('q'):  #如果按下q 就截图保存并退出
    break
  i=i+1
cap.release()
cv2.destroyAllWindows()

图片识别

#!/usr/bin/env python
# BEGIN IMPORT
import rospy
# END IMPORT
# BEGIN STD_MSGS
from std_msgs.msg import Int32
#from modelarts.session import Session
#from modelarts.model import Predictor
import cv2
# END STD_MSGS
rospy.init_node('topic_publisher')
# BEGIN PUB
pub = rospy.Publisher('counter', Int32)
# END PUB
# BEGIN LOOP
rate = rospy.Rate(0.25)
count = 0
while not rospy.is_shutdown():
    rate.sleep()
    session = Session(access_key='******',secret_key='******', project_id='******', region_name='******')

    predictor_instance = Predictor(session, service_id="******")
    predict_result = predictor_instance.predict(data="/home/nvidia/Desktop/1.jpg", data_type="images")
    print(predict_result)
    a=1
    b=2
    c=3
    j=0
	for key,value in predict_result.items():
       	 for i in predict_result[key]:
                	if (i=="黑星病")&(j==0):
                        	print("检测到黑星病即将调用杀毒车")
                        	pub.publish(a)
                        	j=j+1
      	            if(i=="锈果病")&(j==0):
      	                    print("检测到锈果病即将调用杀毒车")
                        	pub.publish(a)
                        	j=j+1
      	            if(i=="轮纹病")&(j==0):
      	                    print("检测到轮纹病即将调用杀毒车")
                        	pub.publish(a)
                        	j=j+1

b车程序:

#!/usr/bin/env python
# BEGIN ALL
#!/usr/bin/env python
import rospy
from std_msgs.msg import Int32
from jetbot import Robot
import time
# BEGIN CALLBACK
def callback(msg):
    print(msg.data)

     if(msg.data==1):
        print("检测到黑星病已调用杀毒车")
        robot.set_motors(0.6, 0.6)
        time.sleep(1.5)
        robot.set_motors(0,0)
    if(msg.data==2):
        print("检测到锈果病已调用杀毒车")
        robot.set_motors(0.6, 0.6)
        time.sleep(1.5)
        robot.set_motors(0,0)
    if(msg.data==3):
        print("检测到轮纹病已调用杀毒车")
        robot.set_motors(0.6, 0.6)
        time.sleep(1.5)
        robot.set_motors(0,0)
# END CALLBACK
rospy.init_node('topic_subscriber')
robot = Robot()
# BEGIN SUBSCRIBER
sub = rospy.Subscriber('counter', Int32, callback)
# END SUBSCRIBER
rospy.spin()
# END ALL

七、ros+modelarts实现智能电梯

程序

1.小车出入电梯

1)小车对应程序
#!/usr/bin/env python
# BEGIN ALL
#!/usr/bin/env python
import rospy
from std_msgs.msg import Int32
from jetbot import Robot
import time
# BEGIN CALLBACK
def callback(msg):
    print(msg.data)

     if(msg.data==3):
        print("进入电梯")
        robot.set_motors(-0.6,-0.6)
        time.sleep(1.5)
        robot.set_motors(0,0)
    if(msg.data==6):
        print("出电梯")
        robot.set_motors(0.6, 0.6)
        time.sleep(1.5)
        robot.set_motors(0,0)
# END CALLBACK
rospy.init_node('topic_subscriber')
robot = Robot()
# BEGIN SUBSCRIBER
sub = rospy.Subscriber('counter', Int32, callback)
# END SUBSCRIBER
rospy.spin()
# END ALL2)电梯对应程序
#!/usr/bin/env python
# BEGIN IMPORT
import rospy
# END IMPORT
# BEGIN STD_MSGS
from std_msgs.msg import Int32
#from modelarts.session import Session
#from modelarts.model import Predictor
import cv2
# END STD_MSGS
rospy.init_node('topic_publisher')
# BEGIN PUB
pub = rospy.Publisher('counter', Int32)
# END PUB
# BEGIN LOOP
rate = rospy.Rate(0.25)
count = 0
while not rospy.is_shutdown():
    rate.sleep()
    count += 1
    print("%d层"%count)
    pub.publish(count)

2.口罩识别

1)口罩识别运行时定时截图
import cv2
cap = cv2.VideoCapture(1)    #打开摄像头
i=100
while(1):
  # get a frame
  ret, frame = cap.read()
  # show a frame
  cv2.imshow("capture", frame)   #生成摄像头窗口
  if i%100==0:
    cv2.imwrite("/home/nvidia/Desktop/1.jpg", frame)  #保存路径
  if cv2.waitKey(1) & 0xFF == ord('q'):  #如果按下q 就截图保存并退出
    break
  i=i+1
cap.release()
cv2.destroyAllWindows()


(2)口罩识别处理 运用AI开发平台ModelArts_华为云平台
from modelarts.session import Session
from modelarts.model import Predictor
import cv2
session = Session(access_key='**************',secret_key='**************', project_id='**************', region_name='**************')
predictor_instance = Predictor(session, service_id="**************")

i=1
time=120
while(1):
   predict_result = predictor_instance.predict(data="/home/nvidia/Desktop/1.jpg",data_type="images")
  print(predict_result)
cap.release()
cv2.destroyAllWindows()

总结

程序不是最难的,最难的是环境的配置。

(2021.2.2)

猜你喜欢

转载自blog.csdn.net/qq_44181970/article/details/113531789