Skip to content

Dev_NewMessageTypes

Martin Bischoff edited this page Oct 31, 2019 · 13 revisions

How to add new Message Types

From time to time, one will realize that the MessageTypes which come with the ROS# repository are not enough for their project. We can't simply include all possible MessageTypes.

Of course you wouldn't want to write a hundred message classes by class so we implemented some magic to ask a computer to do the heavy lifting

Before we start, here is something you need to know...

  • The parent of all ROS# messages and services, no matter their origins, is the RosSharp.RosBridgeClient.Message class

  • They will all bear a constant string called the RosMessageName, their names in an alternative dimension called ROS. One commonly known name "std_msgs/Float32" serves to be an example

  • C# classes of ROS messages will fall under the namespace RosSharpClient.MessageTypes

  • ROS services consists of a Request and a Response. In ROS#, we managed to seperate the two classes and throw them into their own respective C# scripts. For example, std_srvs/SetBool will be split into SetBoolRequest and SetBoolResponse.

  • ROS actions consists of a goal, a result and a feedback. In accordance to the rules of ROS, we split them into 7 classes. For example, actionlib_tutorials/Fibonacci will be split into FibonacciAction, FibonacciActionGoal, FibonacciActionResult, FibonacciFeedback, FibonacciGoal, FibonacciResult and FibonacciFeedback. Phew...How many Fibonacci's do you want?

  • Messages, services and actions will get their own folder after generation, under the folder named after their package name. For example, Nav/msg and Nav/srv

  • What? You slipped in some C# reserved words as field names? Don't worry, we will append an _ in front so C# compiler doesn't complain. You will get a stern warning from us though.

Option 1: Generate Message Types in Unity from local ROS message files

The magic resides in the RosBridgeClient > Auto Generate Messages/Services/Actions menu, depending on the input file type.

There are a few flavors to it. You can choose to generate a single message, messages of a package or all messages under a directory.

1. Single message

In the editor window, find your target by Browse File... and once the message file is selected, we will extract the package name for you assuming ROS folder structure (you can change the package name of course).

The default output folder is Assests/RosSharpMessages but again, you can change that by Select Folder...

When you are ready, just hit GENERATE! and C# script for the message will be ready for you, under RosSharpMessages/PackageName

2. Package message

The editor window looks strikingly familiar right? The only difference is that this time, you will be selecting the folder of your ROS package, and we will chase down and find the message files.

When you are ready, hit GENERATE!

3. Directory message

This time, we will take over package naming since there is probably more than one package under the directory.

Just select the folder that contains all the messages you want to generate, click GENERATE! and relax. A progress bar will let you know the progress

Option 2: Use the console tool with local ROS message files

In a world without Unity, you still get to use the magic in the form of a console tool.

1. Build RosSharp.sln in Visual Studio

  • Open Libraries\RosSharp.sln in Visual Studio
  • In Build > Configuration Manager select:
    • Active Solution Configuration: Release
    • Active Solution Platform: Any CPU
  • Click Build > Build Solution

2. Use the tool, Luke!

  • In your favourite console, navigate to ..Libraries/MessageGenerationConsoleTool/bin/Release
  • Enter ./RosMsgGen.exe to see instructions (which is what you will see below)
  • Add the following flags to enable different functions
    • -v or --verbose Outputs extra information
    • -s or --service Generate service messages
    • -a or --action Generate action messages
    • -r or --recursive Generate message for all ROS message files in the specified directory
    • -p or --package Treat the directory as a single ROS package during message generation
    • -n or --ros-package-name Specify the ROS package name for the message
    • -o or --output Specify output path
  • For example:
    • Generate a single message at the current directory: ./RosMsgGen.exe <input file>
    • Generate a package service at a chosen directory: ./RosMsgGen.exe -p -s <input directory> -o <output directory>
    • Generate actions under a directory with verbose at the current directory: /RosMsgGen.exe -v -r -a <input directory>

Option 3: Handcraft Messages in the RosbridgeClient Library

If you would like to revisit the old craft of creating a C# message class, consult the instructions below:

1. Declare a new message type

Add a new class in Libraries\RosBridgeClient\MessageTypes or any of its subfolders, and make it extend the Message class.

using Newtonsoft.Json;

namespace RosSharp.RosBridgeClient.MessageTypes.Std
{
    public class Float32 : Message
    {
        [JsonIgnore]
        public const string RosMessageName = "std_msgs/Float32";
        public float data;

        public Float32()
        {
            data = 0;
        }
    }
}

2. Build RosSharp.sln in Visual Studio

  • Open Libraries\RosSharp.sln in Visual Studio
  • In Build > Configuration Manager select:
    • Active Solution Configuration: Release
    • Active Solution Platform: Any CPU
  • Click Build > Build Solution

3. Update RosBridgeClient.dll in your Unity Project

Copy RosBridgeClient.dll

  • from ..Libraries\RosBridgeClient\bin\Release\
  • to ...\Unity3D\Assets\RosSharp\Plugins\

4. Use the new MessageType in your Unity Project

Create a new script in Assets\RosSharp\Scripts\RosCommunication.

Example Publisher Script:

namespace RosSharp.RosBridgeClient
{
    public class FloatPublisher : UnityPublisher<MessageTypes.Std.Float32>
    {
        public float messageData;

        private MessageTypes.Std.Float32 message;

        protected override void Start()
        {
            base.Start();
            InitializeMessage();
        }

        private void InitializeMessage()
        {
            message = new MessageTypes.Std.Float32
            {
                data = messageData
            };
        }

        private void Update()
        {
            message.data = messageData;
            Publish(message);
        }
    }
}

Example Subscriber Script:

namespace RosSharp.RosBridgeClient
{
    public class FloatSubscriber : UnitySubscriber<MessageTypes.Std.Float32>
    {
        public float messageData;

        protected override void Start()
        {
            base.Start();
        }

        protected override void ReceiveMessage(MessageTypes.Std.Float32 message)
        {
            messageData = message.data;
        }
    }
}

© Siemens AG, 2017-2019 Author: Sifan Ye ([email protected])

Clone this wiki locally