GithubHelp home page GithubHelp logo

middleware-collection / lcm_to_ros Goto Github PK

View Code? Open in Web Editor NEW

This project forked from nrjl/lcm_to_ros

0.0 2.0 0.0 41 KB

Automatically generate ROS messages and corresponding republishers for LCM messages

CMake 19.26% Shell 68.72% C++ 12.02%

lcm_to_ros's Introduction

LCM to ROS

This package is to subscribe to and republish Lightweight Communications and Marshalling (LCM) messages into ROS messages (and vice-versa). LCM is an open-source messaging tool for high-bandwidth, low-latency communications based on UDP multicast.

The goal is to make a relatively generic system that requires only LCM message files and automatically generate republishers that either:

  1. subscribe to an LCM topic and republish the equivalent (same data) messages onto a ROS topic, OR
  2. subscribe to a ROS topic and republish the equivalent (same data) messages onto a LCM topic.

This package automatically generates ROS message files, CPP files, a launch file and corresponding CMakeLists for catkin_make to create a set of republisher nodes. The system has only been tested on Ubuntu 14.04 with ROS Indigo.

The user should only need to create the *.lcm message files.

Note that this code is restricted to a generating ROS messages from LCM files and not the other way around (partially because LCM has a more limited number of data types but mostly because that's what I needed). The LCM primitive list is available here. We have tested:

LCM Primitive Scalar Fixed length array Variable length array
int8_t
int16_t
int32_t
int64_t
float
double
string n/a n/a
boolean
byte

The LCM primitive types work fine because they can be directly converted into ROS types (really the types are standard data types). It is important to note that the code uses a reinterpret cast to directly refer to the incoming LCM message as a ROS message. This means that you should NOT directly edit the autogenerated msg file, because changing the order of items in the msg with respect to the LCM will mess things up. I'm also not 100% confident in my memory management, but it seems to work. The supplied example code shows an example of all the tested types listed above. Subclass messages work fine and an example is included (the simple_channel message is included in the example_type type message in example_type.lcm).

A possibly better approach would be to try and read out the field names from the message and then set them directly, which might be safer than the pointer cast but uglier in terms of generating the CPP file, possible future work.

Installation:

First, you need to install LCM. Instead of copying the intructions here, I'll link to the LCM build instructions, that contains instructions for various platforms.

LCM Build Instructions

Then, clone this repository (assuming default catkin workspace at ~/catkin_ws):

cd ~/catkin_ws/src
git clone https://github.com/nrjl/lcm_to_ros.git
cd lcm_to_ros

General process

The code works via two primary bash scripts:

  1. rosmsg-gen.sh - This script takes as input a list of lcm message files and, for each file:
    • uses the LCM tool lcm-gen [-x] to generate a CPP header definition for the message,
    • generates a corresponding ROS message type, and
    • if an lcm fingerprint value is supplied as a comment line in the lcm message file (see the lcm/example_type.lcm file), the program also generates a derived class definition that will use the overridden hash value for that message (not usually recommended, if you don't know if you need this, ignore it).
  2. rosrepub-gen.sh - This script takes as input a configuration file and generates CPP code and a ROS launch file for ROS nodes that either:
    • listen to an LCM topic and republish received messages onto a ROS topic, or
    • listen to a ROS topic and republish received messages onto an LCM topic.

Test example

The repo contains a test example. If you haven't added any other LCM messages (or even if you have) you should be able to confirm the code is working by:

  1. Generate ROS messages for all lcm files in your lcm folder by running (at the root project directory of ros2lcm):

     ./rosmsg-gen.sh lcm/*.lcm
    

    This will generate standard LCM hpp message definitions (in the exlcm directory), ROS messages (in the msg directory) and a message definition with an overridden hash value of the example_type (in the exlcm_rehash directory). Feel free to examine (but please don't modify) the ROS message definitions.

  2. Examine the config file repub_configs/example_republishers.cfg. It contains specifications for generating two republishers (one for each non # commented line). The first will subscribe to the LCM topic example_topic of message type exlcm/example_type, and publish messages with the newly-generated ROS message type lcm_to_ros/example_type onto a ROS topic of the same name (example_topic). The second example does the inverse with topic name other_topic but uses the LCM message type with the overridden hash value (using the exlcm_rehash package specifier). Generate the ROS republisher code by running:

     ./rosrepub-gen.sh repub_configs/example_republishers.cfg
    

    This will generate CPP republisher code in the autosrc folder, and a corresponding launch file in the launch directory.

  3. Compile the newly-generated code using catkin:

     cd ~/catkin_ws
     catkin_make
    
  4. Confirm that it worked!

    1. In a new terminal, run the launch file: roslaunch lcm_to_ros example_republishers.launch
    2. In a new terminal:
      • Run rostopic list and confirm that the topics /lcm_to_ros/example_topic and /lcm_to_ros/other_topic exist.
      • Then, show incoming messages using: rostopic echo /lcm_to_ros/example_topic
    3. Finally, in a third terminal: rosrun lcm_to_ros example_send_lcm. This is a small LCM-only (no ROS dependencies) program that publishes a single message onto the LCM topic example_topic
    4. Confirm that a message appears in the rostopic echo terminal.

Generating ROS messages

Add lcm messages to the lcm subdirectory. Some key notes about each lcm file:

  • Package name - The package name is set by the package specifier on the first line of the lcm file. lcm-gen will generate cpp headers in a folder called PACKAGE_NAME.
  • Struct name - The message type will be the struct name specified in the lcm file. The ROS message generated will reflect this, so name each message type with a unique name, even if they have different package names.

Thus, the sample lcm definition example_type.lcm in the lcm subdirectory specifies an lcm message type example_type under the exlcm package. Also note that the repo .gitignore is set up to ignore files (except the examples) in the lcm directory, so that your messages will not be committed to the repo. To generate LCM hpp files and ROS msg files, use:

./rosmsg-gen.sh lcm/MY_LCM_MESSAGE.lcm

or, to generate ROS messages for all .lcm files in the lcm directory, use:

./rosmsg-gen.sh -a 

For both bash scripts, a help message will be displayed with the -h flag.

Generating republisher node code

Once you have generated the ROS messages, create a config file to create republishers. A config file is a simple comma-separated text file (where lines starting with # are assumed to be comments and ignored). I suggest creating them in the repub_configs directory and using the .cfg extension. Add one line to the config file for each republisher you want to generate. Each (non-comment) line should contain a list of four comma-separated values (do not use whitespace in field names):

topic_name, package_name, message_type, direction

Where:

  • topic_name is the name of the lcm topic (the same name is used for the ROS topic, but can be remapped if required)
  • package_name is the name of the package of the lcm message you are using (by default, the rehashed version of the message is generated in original_package_rehash, so you can use that if you want to use the rehashed version of the message, as shown in the example)
  • message_type is the message type (the keyword after struct in the lcm message definition)
  • direction is either the string lcm2ros or ros2lcm. Note that only one is allowed at a time on the same topic to prevent infinite message bouncing. If you need bidirectional messaging there could be some workarounds you could use to filter the messages such as timestamps, but that is not implemented here.

Use the rosrepub-gen.sh script to generate republisher node code from your config file:

./rosrepub-gen.sh repub_configs/CONFIG_NAME.cfg

The program will generate cpp code and a CMakeLists.txt file for these republisher nodes in the autosrc folder. It will also create a launch file in the launch folder corresponding to the filename of the config file. After generating the code it will need to be built with catkin_make.

Once complete, the publishers can be run with:

roslaunch lcm_to_ros CONFIG_NAME.launch

(where CONFIG_NAME is the name of the config file without file extension). Note that this launch file places all republishers under the namespace \lcm_to_ros.
Each republisher can also be launched separately with: rosrun lcm_to_ros TOPIC_NAME_republisher. As usual, output topics can be remapped using standard ROS commands if required.

Rehash tool

LCM uses a special fingerprint calculation to identify messages to ensure that they can be properly decoded using the same specification that was used to generate them. In general, this is an excellent idea. However, in some cases, you may want to specify a specific hash value. The rosmsg-gen tool will attempt to create a version of each message with a user-specified hash value if required. This is not advised, but can be handy when trying to force LCM message types to match for automated decoding. In general I suggest you don't use it, but if you need to, after creating a custom lcm message, add a line at the bottom of the lcm file that specifies a 64-bit fingerprint in the format // HASH 0x0123456789abcdef (as in the example_type.lcm message). This will create a new folder and hpp file with the package name specified in the lcm file appended with _rehash. You can proceed to use this message as usual, as shown in one of the example republishers, and it will force the LCM encoding and decoding to use the specified fingerprint value.

lcm_to_ros's People

Contributors

5yler avatar

Watchers

James Cloos avatar YuehChuan avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.