ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
0

is there a ros serial node to log data?

asked 2020-06-05 14:10:01 -0500

elgarbe gravatar image

updated 2020-06-08 16:46:45 -0500

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.

edit retag flag offensive close merge delete

1 Answer

Sort by » oldest newest most voted
0

answered 2020-06-08 16:07:48 -0500

borgcons gravatar image

updated 2020-06-08 16:15:26 -0500

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.

edit flag offensive delete link more

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.

elgarbe gravatar image elgarbe  ( 2020-06-08 16:48:23 -0500 )edit

Question Tools

1 follower

Stats

Asked: 2020-06-05 14:10:01 -0500

Seen: 263 times

Last updated: Jun 08 '20