系列文章目录
第一章 华为云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 ALL
(2)电梯对应程序
#!/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)