机器人打靶项目问题记录
项目概述:通过结合雷达点云数据和神经网络对视野中的目标进行识别,并通过点云坐标数据获得目标与雷达相对位置,控制与雷达处于同一视角的云台转动,使目标处于雷达坐标系原点,对武器进行标定,使武器能够精确打击目标
通过训练yolov5进行目标识别(训练过程参考另一篇博客)
数据集准备
为保证识别的精度,在不同距离、不同光照、不同背景下分别采集图像数据,训练方案一为不同场景采用不同的模型进行识别,优点为
通过yolov5将到目标,在目标区域内进行圆检测,确定目标靶的靶心位置
代码如下(示例):
data = pd.read_csv(
'https://labfile.oss.aliyuncs.com/courses/1283/adult.data.csv')
print(data.head()
雷达点云融合数据与图像数据在ros框架下通过话题发布和订阅的形式进行传递,image发布格式为sensor_msgs/image,这种格式无法直接获得图像信息,可以通过opencv库中的bridge.msg_to_cv()进行转换,具体用法可自行百度,需要注意的是,python3不支持这个方法,如果必须使用python进行可以参考问题一及其解决方法。通过该方法进行进行转换后可直接得到cv格式的图片数据,即np.uint8格式的矩阵。
代码如下:
def ladar_image(msg):
'''
sensor_msgs to cv2 data, show the image of
lidar camera,
get the theta
'''
global count,bridge,i,image
count = count+1
if count == 1:
count = 0
cv_image = bridge.imgmsg_to_cv2(msg, 'bgr8')
点云融合数据通过自定义消息类型test进行发布,发布话题名为neuvition_driver,消息格式为int64[]的列表类型,长度为image分辨率大小,没有点云的位置采取补0操作,int64格式的数据包含点云的x,y,z坐标,分别保存在列表元素的低20位,中20位,和高20位,单位为mm,为美观起见,数据int64最高四位置零,其中,20位的最高位设置位标志位,如果数据为负数,则置1,这是为了保证在移位操作过程中负数产生的补码导致数据错误,对补码有所了解的应该都明白,哭~~,订阅得到点云数据后需要对数据进行与编码之前相反的操作,得到我们需要的x,y,zz坐标值。再去通过相对位置计算与坐标原点的偏差角度,发布给云台。
代码如下:
def lidar_driver(driver):
'''
获取点云数据
'''
global cloud
cloud = driver.data
def angle_publisher(sum):
'''
输入由坐标系三维坐标通过移位操作得到的值,
输出云台转动的水平角和俯仰角
'''
global angle1,N_angle
x_20 = 0x7ffff
y_40 = 0x7ffff00000
z_60 = 0x7ffff000000000
if sum > 0:
x = sum & x_20
y = (sum & y_40) >> 20
z = (sum & z_60) >> 40
if sum & 0x80000 != 0:
x = -x
if sum & 0x8000000000 != 0:
y = -y
if sum & 0x800000000000000 != 0:
z = -z
print(f"x = {x}\ny = {y}\nz = {z}")
else:
x = (~sum+1) & x_20
y = (~sum+1) & y_40
z = (~sum+1) & z_60
if x & 0x80000 != 0:
x = -x
if y & 0x80000 != 0:
y = -y
if z & 0x80000 != 0:
z = -z
print(f"x ={x}\ny={y}\nz = {z}")
print(sum)
zeta = np.arctan(x/z) + N_angle[0]
arpha = np.arctan(y/(np.sqrt(x**2+z**2))) + N_angle[1]
angle1 = [zeta,arpha]
angle_info_pub.publish(angle1)
节点初始化与话题订阅
def ladar_sensor():
'''
subscribe the data of lidar
'''
rospy.init_node('ladar_subscribe',anonymous = True)
# 创建一个Publisher,发布名为/yt_angle的topic,消息类型为sensor_msg::angle,队列长度10
angle_info_pub = rospy.Publisher('/yt_angle', Angle, queue_size=10)
global count,bridge,i,arf,zeta,N_angle,angle1
angle1 = Angle()
count = -5
bridge = CvBridge()
rospy.Subscriber('/neuvition_image', Image, ladar_image)
rospy.Subscriber('/neuvition_yolov5', Image, yolo)
rospy.Subscriber('/neuvition_driver', test, lidar_driver)
rospy.Subscriber('/云台当前状态话题', Angle, yuntai_sit)
rospy.spin()
if __name__ == '__main__':
ladar_sensor()
描述:由于安装的ros环境ros_melodic默认的python为python2版本,而我们训练的模型一级tensorR推理都是在python3下运行的,在之前没有考虑过接收到数据及其转换的问题,结果就是在python3下订阅ros节点后,拿到的数据无法解析,bridge().msg_to_cv()无法运行。
解决方法:最后是通过在python3中对cv_bridge重新编译,使该方法能够在python3中使用。
参考文档
具体步骤
sudo apt-get install python-catkin-tools python3-dev python3-catkin-pkg-modules python3-numpy python3-yaml ros-kinetic-cv-bridge
mkdir -p catkin_workspace/src
cd catkin_workspace
#注意,该处需要根据你原本自带的系统python版本设定。16.04是python3.5,18.04是python3.6
catkin config -DPYTHON_EXECUTABLE=/usr/bin/python3 -DPYTHON_INCLUDE_DIR=/usr/include/python3.5m -DPYTHON_LIBRARY=/usr/lib/x86_64-linux-gnu/libpython3.5m.so
git clone https://github.com/ros-perception/vision_opencv.git src/vision_opencv
提示:
如果开发设备连不上网,也可以直接到GitHub下载下来复制到相应文件夹进行编译安装
apt-cache show ros-kinetic-cv-bridge | grep Version
cd src/vision_opencv/
git checkout 1.12.8#必须要编译否则cv_bridge的CMakeLists默认版本为python37
cd ../../
#有可能会有warning,不用管,只要不报错就行
catkin build
或者 catkin build cv_bridge
source install/setup.bash
或者按照前文提到的方法将环境变量编辑到.bashrc文件
:
如果遇到python自动加载python3中的cv_bridge的情况,可以在导入cv_bridge库时将python原本的路径删掉,将你编译的库的路径添加到里面,操作如下:
sys.delete(“pathon默认路径”)
sys.add(“自己编译的库的路径”)
这个方法在你编译的其他库需要导入时同样适用。
未完待续…