is there a ros serial node to log data?
Is there a ROS package that takes serial port data and publish it on some topics? It would be very usefull, for logging serial data from sensor like GPS, ecosounder... I can't find any...
Thank
EDIT1: Based on this code I write this node and now I'm testing it:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""Defines the main method for the nmea_serial_driver executable."""
import serial
import sys
import rospy
from ect400.msg import FloatStamped
class ECT400Node(object):
"""
ROS parameters:
~port (str): Path of the serial device to open.
~baud (int): Baud rate to configure the serial device.
"""
def __init__(self):
serial_port = rospy.get_param('~port', '/dev/ttyUSB0')
serial_baud = rospy.get_param('~baud', 115200)
# Creo que publisher que envía los datos al tópico pedido
self.ect_data = rospy.Publisher(
"depth_data",
FloatStamped,
queue_size=10)
try:
GPS = serial.Serial(port=serial_port, baudrate=serial_baud, timeout=2)
try:
while not rospy.is_shutdown():
data = GPS.readline()#.strip()
# rospy.loginfo("[ECT400] Data from sensor: %s", data)
data = data.split(",")
if len(data) == 7:
depth = float(data[3])
# print depth
# Armo el mensaje a publicar
message = FloatStamped()
message.header.stamp = rospy.Time.now()
message.data = depth
self.ect_data.publish(message)
# try:
# driver.add_sentence(data, frame_id)
# except ValueError as e:
# rospy.logwarn(
# "Value error, likely due to missing fields in the NMEA message. "
# "Error was: %s. Please report this issue at "
# "github.com/ros-drivers/nmea_navsat_driver, including a bag file with the NMEA "
# "sentences that caused it." %
# e)
except (rospy.ROSInterruptException, serial.serialutil.SerialException):
GPS.close() # Close GPS serial port
except serial.SerialException as ex:
rospy.logfatal(
"Could not open serial port: I/O error({0}): {1}".format(ex.errno, ex.strerror))
def shutdown(self):
"""Unregisters publishers and subscribers and shutdowns timers"""
rospy.loginfo("[ECT400] Sayonara Robot Adapter. Nos vemo' en Disney.")
def main():
"""Entrypoint del nodo"""
rospy.init_node('ect400_driver', anonymous=True, log_level=rospy.INFO)
node = ECT400Node()
try:
rospy.spin()
except KeyboardInterrupt:
rospy.loginfo("[ECT400] Received Keyboard Interrupt (^C). Shutting down.")
node.shutdown()
if __name__ == '__main__':
main()
It seems to work ok, but I would like to take some posible erros into account.
Asked by elgarbe on 2020-06-05 14:10:01 UTC
Answers
Hi
What we have done is to create a serial node and publish to a string topic. We have done the same for a tcp and udp node as well.
For serial node you have to decide is you want to publish from a read or publish on a terminator. For ASCII protocols its usually done by ending with a terminator. So your serial node should be of type ASCII or BINARY. For ASCII it would send on a parameterized terminator. For BINARY it would send whatever the read returns. It would be the responsibility of the high node receiving the BINARY data to assemble the data into a packet.
BTW you will have to you assign to move the data from the serial port to the string topic.
Hope all that helps.
Separating in serial into a string topic also makes testing, and debugging easier. An extra feature is that if you have the same type of device, like a GNSS/GPS, that returns apacket of UDP instead of serial your GNSS/GPS node does not have to change. We actually ran into this situation and all that was required was to change a launch file.
Asked by borgcons on 2020-06-08 16:07:48 UTC
Comments
Hi, thank to your help. Could you share your code? I was thinking that serial received data should be in another thread that the ros node, but I've try all in the same thread and seems to be working ok.
Asked by elgarbe on 2020-06-08 16:48:23 UTC
Comments