目前,我正在开发具有多个传感器的ROS系统通过各种接口。 GPS中最重要的两个传感器通过RS232-USB适配器连接的陀螺仪和陀螺仪。
我想强调一点,我无论如何都不是熟悉或专家在串行连接中。
我使用python读取串行数据并将其发布到ROS-topic和通过Matlab Simulink订阅它们。
我同时使用了一个GPS和陀螺仪,没有根本没有问题(来自不同制造商的适配器用于假设每个都有2个RS232-USB适配器制造商; TA和TB)。
出于某些目的,我决定安装一个额外的GPS(因此2GPS和陀螺仪同时使用)。假设我将那两个GPS放得很近;小于1m。
这两个GPS的串口设置相同(波特率相同,奇偶校验,相同的停止位,相同的更新频率等),并且我使用了两个GPS的RS232-USB适配器TA类型相同。
但是,在Matlab中进行订阅时会有很大的延迟Simulink(我使用了模拟数据检查/记录器)。 GPS之一来晚了!我最近的意思是说一个GPS并没有真正更新时间。
例如,在t(时间)= 3,两个GPS都应在p(位置)= 10。但一个GPS在40〜60秒后到达p = 10。全球定位系统这是正确的(时间与位置是实时的)。我在下面附上一张图表。 那两条曲线不应该那么远
编辑(12/11/2019 12:34 GMT + 9)[下面是我为一个GPS编写的代码,对于其他GPS我只是创建一个新的.py,并使用完全相同的代码,但节点名称和rostopic不同。
#!/usr/bin/env python
import serial
import types
import re
import rospy
import time
import threading
from datetime import datetime
from shipcon.msg import gps_position
from shipcon.msg import gps_local_position
from shipcon.msg import gps_navinfo
from shipcon.msg import gps_time
#Constants-----------------------------------------------------------------------------------------
PUBLISH_RATE = 10 #Hz
SERIAL_PORT = "/dev/ttyUSB1"
BAUD_RATE = 115200
#Class-----------------------------------------------------------------------------------------
class GpsSerial:
def __init__(self, serial_port, baud_rate):
self.gpsArr = []
self.gpsStr = ""
self.pos = gps_position()
self.localpos = gps_local_position()
self.navinfo = gps_navinfo()
self.time = gps_time()
self.ser = serial.Serial(
port = serial_port,
baudrate = baud_rate,
parity = serial.PARITY_NONE,
bytesize = serial.EIGHTBITS,
stopbits = serial.STOPBITS_ONE,
timeout = None,
xonxoff = 0, #Enable software flow control
rtscts = 0, #Enable Hardware(RTS,CTS) flow control
)
def get_gps(self):
self.gpsStr = self.ser.readline()
self.gpsArr = self.gpsStr.split(',')
if re.match(r"^\$.*", self.gpsArr[0]):
if self.gpsArr[0] == '$PTNL':
if self.gpsArr[1] == 'GGK':
self.pos.latitude_deg = int(float(self.gpsArr[4]) // 100)
self.pos.latitude_min = float(self.gpsArr[4]) - (self.pos.latitude_deg * 100)
self.pos.latitude_dir = self.gpsArr[5]
self.pos.longitude_deg = int(float(self.gpsArr[6]) // 100)
self.pos.longitude_min = float(self.gpsArr[6]) - (self.pos.longitude_deg * 100)
self.pos.longitude_dir = self.gpsArr[7]
self.pos.gps_quality = int(self.gpsArr[8])
self.pos.satellite_number = int(self.gpsArr[9])
elif self.gpsArr[1] == 'VGK':
if self.gpsArr[4] =='-' or self.gpsArr[4] == '':
pass
else:
self.localpos.localpos_e = float(self.gpsArr[4])#float( re.sub(r'\+', "", self.gpsArr[4]) )
if self.gpsArr[5] =='-' or self.gpsArr[5] == '':
pass
else:
self.localpos.localpos_n = float(self.gpsArr[5])#float( re.sub(r'\+', "", self.gpsArr[5]) )
if self.gpsArr[6] =='-' or self.gpsArr[6] == '':
pass
else:
self.localpos.localpos_z = float(self.gpsArr[6])#float( re.sub(r'\+', "", self.gpsArr[6]) )
elif self.gpsArr[1] == 'VHD':
self.localpos.local_azimath = float(self.gpsArr[4])
self.localpos.local_vertical = float(self.gpsArr[6])
self.localpos.local_range = float(self.gpsArr[8])
elif self.gpsArr[0] == '$GPGST':
self.pos.latitude_err = float(self.gpsArr[6])
self.pos.longitude_err = float(self.gpsArr[7])
self.pos.ellipse_err_maj = float(self.gpsArr[3])
self.pos.ellipse_err_min = float(self.gpsArr[4])
self.navinfo.truenorth_heading_err = float(self.gpsArr[5])
elif self.gpsArr[0] == '$GPROT':
if self.gpsArr[1] =='-' or self.gpsArr[1] == '':
pass
else:
self.navinfo.rotation_rate = float(self.gpsArr[1])
elif self.gpsArr[0] == '$GPVTG':
if self.gpsArr[1] =='' or self.gpsArr[5]=='' or self.gpsArr[7]=='':
pass
else:
self.navinfo.truenorth_heading = float(self.gpsArr[1])
self.navinfo.speed_knot = float(self.gpsArr[5])
self.navinfo.speed_km = float(self.gpsArr[7])
elif self.gpsArr[0] == '$GPZDA':
tmptime = datetime.strptime(self.gpsArr[1]+','+self.gpsArr[4]+self.gpsArr[3]+self.gpsArr[2], '%H%M%S.%f,%Y%m%d')
self.time.day = tmptime.day
self.time.month = tmptime.month
self.time.year = tmptime.year
self.time.hour = tmptime.hour
self.time.min = tmptime.minute
self.time.sec = tmptime.second
elif self.gpsArr[0] == '$GPGGA':
self.pos.latitude_deg = int(float(self.gpsArr[2]) // 100)
self.pos.latitude_min = float(self.gpsArr[2]) - (self.pos.latitude_deg * 100)
self.pos.latitude_dir = self.gpsArr[3]
self.pos.longitude_deg = int(float(self.gpsArr[4]) // 100)
self.pos.longitude_min = float(self.gpsArr[4]) - (self.pos.longitude_deg * 100)
self.pos.longitude_dir = self.gpsArr[5]
#self.pos.gps_quality = int(self.gpsArr[8])
#self.pos.satellite_number = int(self.gpsArr[7])
class RosPublish:
def __init__(self):
self.pub_pos = rospy.Publisher('gps_position', gps_position, queue_size = 1)
self.pub_localpos = rospy.Publisher('gps_localposition', gps_local_position, queue_size = 1)
self.pub_navinfo = rospy.Publisher('gps_navinfo', gps_navinfo, queue_size = 1)
self.pub_time = rospy.Publisher('gps_time', gps_time, queue_size = 1)
def ros_log(self, pos, localpos, navinfo, time):
rospy.loginfo(pos)
rospy.loginfo(localpos)
rospy.loginfo(navinfo)
rospy.loginfo(time)
def ros_pub(self, pos, localpos, navinfo, time):
self.pub_pos.publish(pos)
self.pub_localpos.publish(localpos)
self.pub_navinfo.publish(navinfo)
self.pub_time.publish(time)
#Function-----------------------------------------------------------------------------------------
def publish_gps(gps):
rospy.init_node('NODE_Gps', anonymous = True)
ros = rospy.Rate(PUBLISH_RATE)
pub = RosPublish()
pub.ros_log(gps.pos, gps.localpos, gps.navinfo, gps.time)
pub.ros_pub(gps.pos, gps.localpos, gps.navinfo, gps.time)
ros.sleep()
def refresh_gps(gps):
while not rospy.is_shutdown():
gps.get_gps()
#Main-----------------------------------------------------------------------------------------
if __name__ == '__main__':
try:
gps = GpsSerial(SERIAL_PORT, BAUD_RATE)
thread_1 = threading.Thread(target = refresh_gps, args = (gps,))
thread_1.start()
while not rospy.is_shutdown():
publish_gps(gps)
except rospy.ROSInterruptException:
pass
我使用Matlab订阅并记录了传感器的所有数据。目前,我在Matlab中所做的唯一计算只是将GPS纬度/经度数据转换为XY坐标,以获取我船的实时轨迹。此转换是非常简单的计算,我认为不会造成严重的延迟。
如果您能给我解决方案,甚至是真知灼见,赞赏。非常感谢。
最诚挚的问候
目前,我正在通过各种接口在具有多个传感器的ROS系统上工作。两个最重要的传感器是GPS和陀螺仪,它们通过RS232-USB适配器连接。我会...