Skip to content

MicroROS runtime IDL compiler and data manager to provide Message interface between MicroROS and MicroPython

License

Notifications You must be signed in to change notification settings

gentijo/MicroROS-RTIDL

Repository files navigation

Note: This Repo is to evaluate a POC for managing ROS msg's in a Python environment, it has not been optimized, it not code complete, nor is it pretty and is basically a hack to provide a real world example.

The Data Transfer agent or build-in common base Classes, are not part of this project so that the focus can stay on the compilation process and it's outputs



Problem Statement

While developing the Micropython integration for MicroROS, it became apparent that there was a need to provide native python interfaces for the .msg files in MicroROS as it would be too cumbersome to write C code that would produce a C/C++ class that would interface ROS Types to Micropython. This would require C Coding and a recompile of the ROS image which may beyond the scope of the Python programmer and may also cause problematic drift between images loaded on various devices where a embedded type may be missing requiring that all devices be upgraded to the latest image.


Propose Solution

Create a small footprint Parser that will be able to build a memory based Data Transfer Instruction structure that provides information to a generic data marshaling engine can use to marshal ROS msg data to/from Python. This will be coupled with a template based python class generator to allow the Micropython code to selectively use all existing .msg files or create new msg types at runtime without the need for a recompile of the device image.

As an example, take the Twist msg which consists of 2 Vector3's which in themselves are a collection of 3 floats. 

The parser would build a Data Transfer instruction list, where the DTEngine will allocate memory for the full msg size, then copy data to/from by using a void pointer that will copy data to structure for the native types. Continuing with the Twist example, Twist defined two types of Vector3, which each consist of 3 Float64, a native type. Example DTI definition for Twist

  • 1.0 Vector3 Linear
    • 1.1 Float64 x
    • 1.2 Float64 y
    • 1.3 Float64 z

  • 2.0 Vector3 Angular
    • 2.1 Float64 x
    • 2.2 Float64 y
    • 2.3 Float64 z

Would result in a memory allocation of Float64 x 6, then a routine that will walk thru the primitive types and perform

ptr = copyToRos(ptr, Float64) where the return value will be incremented by sizeof(float64) on each call.

Data flow from ROS to Python will be defined when registering the listener for a message. the Python code

registerMsgListener("cmd_vel", Twist, pythonCallBack)

would instruct the Data Transfer Engine to create a Twist python object and populate the named values using the DTI definiton on recipt of the message.

Here is an overview of the data flow to produce the DTI definitions and artifacts

How this would work on the device.

First upload .msg files along with the dependant .msg files to the device storage In python there will be a MicroROS.py that is builtin to the device that support MicroRos operations In boot.py, you would import ROSType then add statements for all the ROSTypes you want to use on your device

from MicroROS import ROSType

ROSType.registerType(TypeName, msgDir, pyDir)


This would create and register the DTI structure in a memory based map It would also create the .py artifacts in the pyDir

Then in your code you send a message with

from Twist import Twist

from MicroROS import ROSMessages

twist:Twist

twist.linear.x = 0

twist.linear.y = 0

twist.linear.z = 0

twist.angular.x = 0

twist.angular.x = 0

twist.angular.x = 0

ROSMessages.publishMsg("/cmd_vel", twist)

Running the example Code as a Linux command line app.

In the project root dir execute

  • buildNode.sh
  • startNode.sh

to create the docker image

then connect to the running docker container using the temrminal app

Inside the terminal app execute:

  • cd /opt/rosbots-rtidl/test
  • sh run.sh

Inspect run.sh to see the parameters to try different types

If you are on a Linux host, you can also just cd to the test directory and run the same command

Make sure to remove the contents of the Output dir to see new files build.

You can use any other ROS type although the current parser does not support constant or array types.

Example Code.

Alternatives to this approach

This POC code could be ported back to Python using ANTLR and added as an extension to RShell to parse, produce output files and directly load the final output to the device. This could be further extended to be used as an extension to Visual Code Studio or Thonny


Notes:

About

MicroROS runtime IDL compiler and data manager to provide Message interface between MicroROS and MicroPython

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published