ROS Driver Common Interface Standards

That’s the thing: I don’t think you want to enforce such an interface. You want to encourage its use, and there are many techniques that can be used to do so, such as putting an obvious notice on a package’s index.ros.org page when it does meet the interface.

So what do you think is the best approach for determining the common interface for a set of devices in order to submit a REP?

The interface needs to be very well thought out in order to stand the test of time and work with diverse devices. It is almost a philosophical problem of determining the essence of something like a camera or motion controller that is shared by all specific implementations of those devices.

Would the best interface evolve over many iterations as new drivers are added and needs are discovered? Or would all of those changes be a nightmare once lots of drivers depend on that interface? Is it better to do lots of research and debating before committing to any interface? What if that ends up taking a very long time meanwhile all driver writers have to guess an interface to use until the official one is accepted?

I imagine many people must have studied and thought about this before. I think @vmayoral referenced some of these studies when writing about HRIM. Are there common interfaces already out there and accepted so we do not have to start this process from scratch?

Write a draft REP and put it up for discussion. There are several good places to start from already, such as HRIM and existing de facto industrial standards.

If you try and achieve the perfect interface before you submit anything to the community, you will never get anywhere. ROS interfaces are allowed to change between releases, and there is a defined process for how to revise a REP. It may not be spectacularly fast, but it’s a process that has been proven in large communities such as Python.

I think a good starting point would be to collect a number of existing implementations and extract some kind of best practices from them. Unfortunately, nobody replied to my question about best practices for motor drivers (since that was part of your original question).

@ipa-led Thanks a lot for the mention.

The ros-model tooling (https://github.com/ipa320/ros-model) is being developed within the project SeRoNet (https://www.seronet-projekt.de/en/home.html) with the main objective of connecting ROS with other component-based frameworks using a MDE approach.

For that, I created a family of metamodels to describe the ROS concepts and I use the eclipse facilities (EMF+Xtext) to define a formal structure (kind of DSL) with graphical and text editors where I can also perform some validation steps.

How is this related to the topic of this discussion? These models can be used to create common specifications. You can find some templates under GitHub - ScalABLE40/scalable_component_model: ROS Model storage for ScalABLE Software and Hardware Components where, for example, a 2d laser scanner model is described like:

PackageSet { package {
	CatkinPackage laser_scan{ artifact {
		Artifact  laser_scan { node Node { name Laser_scan 
                      publisher { Publisher { name "/laser_scan" message "sensor_msgs.LaserScan" }}}}}}}}

To extract the models, as @ipa-led mentioned, I use the HAROS framework where I added a special plugin to detect the relevant information and translate it to my DSL. And finally to facilitate its use I offer the extractor as a web service http://ros-model.seronet-project.de/ where you can extract the interfaces of your code (if it is publicly available). The interface supports currently only cpp code but I have already a beta version supporting python and I am planning to extend it to ROS2 code.

Ideally, this can be used for:

  1. Large scale analysis of code, detect common patterns and update the dictionary of specification models (or standard, but I have also thought that this word is too ambitious)
  2. Generate the model of your target component and compare it with the specification (which is one of the functions of the tooling https://github.com/ipa320/ros-model/blob/master/docu/CompareSpec.md)

For now, and because it hasn’t been my main objective, the number of common speficiations I have is quite poor but it is quite easy to extend it. Also, the integration of the HRIM effort is a pending ToDo of my list.

Sorry if the answer is now a bit out of the topic… :roll_eyes:

3 Likes

@ipa-nhg how does your model-based approach compare to the RobMoSys approach? Using models seems like a really good way to define interfaces, especially when they model the whole hierarchy of abstractions at the same time to make sure they are all consistent with each other.

REP maintenance could get tricky when the REP count gets high and they start to depend on each other, either explicitly or implicitly. Changes in one could have a whole cascade of effects. Is there some way of making sure everything remains interoperable when interfaces change?

Interfaces may need to change over time to include more devices. Is better to keep interfaces simple, even if that limits the devices they work with, or make them more generalized and complicated, even though most people may not need or want that extra complication?

For example, the nice camera interface that @christian proposed works well for many cameras. Then what happens when someone wants to add something like a camera that outputs multiple regions of interest? Should a whole new interface get created or should the simple interface get generalized? The GenICam interface works with lots of cameras, but it is way more complicated than just delivering an image. Is a good interface as simple as possible or as generalized as possible or somewhere in between?

1 Like

@peterpolidoro RobMoSys and SeRoNet share the same tooling infrastructure, and, consequently, the same structure of models. That means the models I generate and my DSLs are compatible with RobMoSys, actually I have added a button to automatically convert my models to the RobMosys ones (using model-to-model techniques). In comparison to RobMoSys, my approach is based on ROS “every-day” code, being my starting point the code developed by the ROS community and not a generic model or abstract representation. In other words, I use a bottom-up approach instead of the classical model-to-text of MDE.

I have a DSL associated with my models and also all the required machinery to interpret the language and transform it into other models or to text automatically. Create a new template that generates automatically some text (in the form of a REP for example) from a model is, with my current infrastructure, very easy. But I can also imagine an Eclipse independent software (a model parser written in python for example) with the same functionality, it is quite trivial and can be automatized as a Docker job.

I am providing, for now, only the infrastructure. The definition of the models I think requires some consense within the community (or the working groups within the community).

In my humble opinion, the specifications should be as simple as possible and then you can have specific models for specific uses cases or applications. For example for me, the minimum requirement of the driver of a 2D scanner is a publisher of a sensor_msgs/LaserScan but for my applications, the requirement changes and the driver has also to publish a diagnostics_msgs/DiagnosticsArray. Honestly from my point of view, for all the low-level drivers publish a diagnostic message is highly recommended but I will not “impose” it as a rule because, I said before my approach is based on ROS “every-day” code, and I am pretty sure that the majority of the existing drivers don’t fulfill this requirement.

3 Likes

I like this approach, and also agree that diagnostics is recommended but optional. Maybe instead of binary (yes/no) compliance checks, a levels concept would be useful, but not necessarily right away.

Btw, for diagnostics, it would be great to specify the keys to include.

1 Like

@ipa-nhg your approach is really interesting! Are you working directly with the RobMoSys and ROS-MDD people or are they aware of your efforts? The key to all of this would be for everyone to work together so our efforts reinforce each other rather than compete with each other.

How can the rest of us help and contribute to your approach? Do you have a set of models that the community needs to define? Or is it first necessary to figure out what models are even needed? Are your model interfaces more method-centric, like classes or many APIs, or more data-centric, like DDS or databases, or some combination?

Yes it would be great if your infrastructure was extended to be Eclipse independent with an exporter for ROS REPs. What were you thinking about absorbing or using from HRIM?

Yes perhaps interfaces should be as simple as possible with the ability to extend them or combine them into more complicated devices. For example, if we used the simple joint interface that was only concerned with positions and velocities and perhaps accelerations and efforts, that could work for a whole set of actuators. If the particular actuator happened to be an electric motor, we could extend that interface to include things like current limits. There might be an encoder interface added that handles the position and velocity feedback or maybe the added interface would be for a stepper motor with implied feedback from the open loop control.

Beware of going too far down the model-based rabbit hole. Although I am a fan of model-based approaches myself, it is easy to make something that ends up being too complex and difficult to use to spread widely. Instead, focus on making a simple approach that works and building model-based tools on top of that.

2 Likes

@gbiggs I thought I heard the RobMoSys people mention during their IROS workshop that they had worked with you or talked to you about some of their models, perhaps related to their safety analysis. Maybe I am mistaken about that however. So you do not think that their approach of starting with models is a good idea? Seems like a shame if all the work they are doing in their community cannot compliment and contribute to all of the work going on in the ROS community and vice versa.

I don’t think my approach collides with RobMoSys efforts, I think we are working at different levels. My objectives about the models and the information that can be represented is less ambitious, basically because I am a ROS developer and not an expert on models. However, as we share in the project SeRoNet with RobMoSys the tooling infrastructure, my work is compatible with RobMoSys.

About HRIM, I definitively have to take a look at it and try to merge both approaches.

If I understood correctly the idea is create a set of specifications or design patterns for ROS common components. For me that means: which type of interfaces offer my node/component/system “at runtime”? being interfaces topics, services and action and the communication object that send (.msg, .srv, .action). That is exactly the concepts you can describe with my model (together with more information like name of the rospackage or name of the executable … that is completely irrelevant here). For this we need to know the components we want to describe and identify the common generic pattern that describes this component (complete, simple and useful), I think this is the most challenging part that probably has to involve more people. Put this information into my grammar is easy, I have graphical and text editors for that. About an eclipse-independent parser to auto-generate kind of REPs I can volunteer my self to implement the code, I just need an example as template.

I think that from an engineering point of view, not using models is wilfully ignoring good engineering tools. It’s like if you asked an aeronautical engineer not to use finite element analysis and just stick to building tiny aeroplanes and putting them in wind tunnels.

However the reality is that if you want people to start using common interfaces, not just common data types, you have to make a tool that works at the level the majority of people work at. Then you build better tools on top of that.

I wouldn’t say it can’t. But, generally speaking, they are starting from different premises when modeling systems. Even though, in principle, on the foundational level, the approaches are not incompatible, in practice the connection is not easy for purely practical reasons like tooling, and the Component-Port-Connector approach having different customs than topic-based connectivity. People are still trying, of course, like Nadia does, but its not like it’s totally straightforward. So, given that many people want to solve a different problem initially, this is just slowing things down.

Of course everybody knew going in that if they don’t use ROS, these kinds of purely practical problems will occur, but there’s some history here :wink:

seems like a related/relevant PR:

1 Like

I am not familiar with any of the history between the communities so I guess I was being naive about mixing those worlds.

Yes the Node IDL discussion is very interesting.

Even if the common interfaces are purely ROS definitions of topics, services, and actions, I am still curious about what else needs to be agreed upon in order to be able to easily exchange one package or node for another that shares the same interface.

For example, does that mean we should avoid defining messages and services within a package we might want to exchange and instead define them in common interface packages, like a motor interface package or a camera interface package on which the other packages depend?

This (hosting .msg, .srv and .action in separate packages) has always been considered best practice. Regardless of how the “node interface” is defined.

Late on the game and I got a bit confused about what problem(s) people here are talking about. I feel there are 2 different problems for 2 different audiences being discussed, revolving around the term “interface”.

Problem-1

  • Runtime interface of driver packages of the same kind (camera / motor etc.) are different so the packages that runtime_depend on them need to be modified per driver to depend on.
  • Who would be affected the most?: Downstream developers from the driver packages.
  • Approaches discussed so far include: Node-to-node messaging interface-level organization (e.g. REP, best practice).

Problem-2

  • Program (build-time, not run-time) interface of driver packages of the same kind (camera / motor etc.) are different so the code-level implementation of driver packages varies. This may also result in limiting software design approach e.g. MDE.
  • Who would be affected the most?: Developers and maintainers of the driver packages.
  • Approaches discussed so far include: Programming language-level interfacing?

These may not reflect all discussions, but might be rather opinionated. Sorry if so. But for whatever the problems we’ve been talking about, the end result I think is the waste of effort and likely result in affecting the software quality issues, with or without noticing.

Without fully understanding what is the problem that those insist on “Problem-2”, “Problem-1” seems to me more impactful so is on higher priority? Nice thing is that it sounds like the discussed approaches are just one or a few steps further from what’s already been done widely.

That said, I’d add one more point to Problem-2. As I kind of prowled above, lack of code-level organization among driver packages might have raised a bar for driver package maintenance. And that may have contributed to orphan-ing legacy driver packages. I took over maintenance of some sensor driver packages and wondered if there had been more commonality between these packages code maintenance would’ve been easier. However, as I’ve read through this thread so far, it seems like a difficult problem.

Also, remember a driver package can be written in ROS-agnostic way, then (thin) ROS-layer can be added on the top, as Quigley et.al’s 2009 paper suggests (citing below for convenience. 11-year old, but this particular concept is still very valid I think). Maybe something to keep in mind if we take a next step (REP etc.):

Lastly @ipa-nhg, I’d like to hear you presenting about your approach, maybe at ROSCon? Quite interesting.

This may be tangential, but recently @esteve from Apex.AI contributed new code for ROS 2 drivers that moves code for receiving UDP packets, serial messages, etc. into a separate entity, which allows drivers that use that sort of communication (such as Velodyne LiDARs) to focus on the protocol and ignore the communication aspects. It’s just one part of the problem, but an important part for making writing and maintaining drivers easier.

2 Likes

@gbiggs do you have a link to the code from @esteve so we can read more about it? Do you mean the Velodyne driver within the Apex.AI gitlab repository or something else? Are you suggesting that this driver could be used to create a more generic driver template that we can use for all drivers? Or is that what he already created? That would be really nice to have when creating new drivers or updating old ones.

@130s you have a good point about the multiple uses of the term interface. I think most of us who want to both write and use drivers are affected by both Problem 1 and Problem 2 that you described.

I recently have been trying to convince groups of scientists to agree to use ROS as a way to connect all of the heterogenous software and hardware that they use in their experiments. Right now they do not agree on much of anything and use various programming languages, operating systems, sensor, and actuator brands. There is enough commonality in what all of the experimental rigs do, though, that I think it could be extremely beneficial to all of them if they could just agree on something, anything, to connect all of their pieces together without having to redevelop the same sorts of communication schemes over and over again. I have been using ROS for about 10 years to control experimental rigs and I think it works fantastically. Many scientists can only accept something that runs well on Windows and with Matlab, however, so I never had much of a chance of convincing them to try ROS until recently. As a first step I just want to write thin ROS wrappers around common sensor and actuator drivers provided by the various manufacturers so the scientists can use them interchangeably. I am finding that getting people to agree on anything is a WAY more difficult challenge than any technical problem, but I have hope for the first time in years that maybe there is a common path forward.