Hi everybody,
this is a very useful group with some great ideas!
First, let me briefly introduce my background to you. The main purpose of using robots in our lab is to have an illustrative and graspable demonstrator for the application and development of real-time operating systems. We developed a simple robot equipped in its basic variant with an embedded board which is based on a 32-bit TriCore (TC1796) microcontroller and BLDC-motors. The embedded system is running a multi-tasking operating system with hard real-time characteristics (PXROS-HR). The RTOS utilizes the hardware memory protection unit (MPU) of the TriCore to protect memory areas of any arbitrarily chosen small size, e.g. to encapsulate tasks (each task has a certain amount of memory allocated and if it tries to reach out of this area, an access violation is detected by the MPU and a trap is triggered). Thereby, error propagation throughout the system is prevented.
Of course, in this environment due to memory and performance restrictions it’s impossible to implement sophisticated robotic applications. So we added an embedded PC (Intel Atom) which runs ROS, and connected it to the TriCore board to provide higher level functionality, e.g. navigation tasks. The fantastic aspects about ROS are that real scenarios can be implemented straightforward and the whole environment (including the RTOS) seems to be more interesting to students. Robots are just very attractive :D I totally agree, it would be nice to have something like a minimal ROS client library for small embedded devices to facilitate the development of a distributed environment that looks more homogeneous.
There are some preliminary ideas, of which a few have already been discussed here, nevertheless in the following I’d like to summarize what’s crossing my mind concerning the topic.
What I’d like to have: I’d like to be able to develop ROS real-time nodes that are running on a RTOS. Of course, these nodes could easily be used to interact with an existing (Linux-based) ROS system. There are some parts of a distributed ROS application which have to run under real-time constraints (motor control, failure recognition, etc.) and some of them which don’t necessarily have to (e.g. visualization of maps). If there is interaction between real-time and non-real-time code, failures must be appropriately recognized. An example: there is a navigation node on a non-real-time device (Linux ROS) which sends motor control messages to a real-time motor-control node (RTOS ROS). In that case the real-time environment must be able to recognize whether or not control messages are received and handled within a given time frame and react in an appropriate and well defined way, e.g. by stopping the motors.
The reality: There are some obvious arguments against porting roscpp as it is to an embedded device. The current communication environment is time and space consuming since it uses XML to negotiate direct connections. Furthermore, the use of std::strings is forbidden in safety critical environments (global and dynamic memory allocation). Most parts of boost are also not suitable for our real-time environment. Threads do not exist (for a good reason). Under these circumstances porting roscpp as it is to our system isn’t a suitable option.
Some ideas to tackle the problem: One obvious pitfall is the use of XMLRPC. Perhaps, an alternative/complementary roscore/master (but keeping the code base the same has advantages of course) or an appropriate “less_time_and_space_consuming_protocol_for_the_embedded_side <-> XMLRPC” bridge to the master (something like rosserial) can be implemented on the standard ROS Linux side. For example, this could be realized with the protocol buffers of google. There already exists a lightweight implementation of protobuf for embedded devices (nanopb). But I don’t know how XMLRPC is used by ROS in detail (just sniffed a little bit around with Wireshark) and if protobuf fits well enough (I remember a ROS related discussion on the web where this has been issued before with some arguments against protobuf, especially due to the need of arrays). As I said before, the apparent benefit of using protobuf is that there already exists a quite good implementation on the embedded side which could be used to implement a very minimal ROS client library. In that context, it would be helpful to have a generator which generates protobuf code to (de)serialize messages from ROS message IDL definitions. There is a ROS SIG (msgIDL) which aims at the integration of an external library for message IDL into ROS. I haven’t had time to dive into that topic deeply, yet, but maybe their aim could also be of special interest in this group. Unfortunately the group seems to be inactive?!
Altogether, it would be really great if I could develop a ROS node on an embedded system which is capable of communicating with the ROS master on the Linux system. But still, this master stays a bottleneck and potential pitfall. The master requires every node on the embedded device to communicate with it (if the nodes on the embedded device need to communicate), even if no direct interaction between the embedded device and the pc is required. It’s possible that I got something wrong, but that’s my current understanding of the ROS master...
This directly leads to the next point on the wish list: a small master node on the embedded device (maybe redundant to its Linux equivalent) or even something which does the job statically beforehand by generating a lean implementation. I haven’t thought about this in detail yet, but the first use case definitely requires mechanisms to synchronize the master nodes . Everything which can be realized at compile time should be preferred, so generating might be a serious alternative or even a combination of both.
In my opinion, it would be valuable to have a RTOS involved in a ROS environment not simply to add the essence of fault tolerance to it, even if that only means “stop the motors immediately in any case if this fault occurs”, but also to treat real-time relevant parts such as a motor controller appropriately. Homogeneity on an abstract level would be great and that’s why I’d like to have a ROS integration. I’d just like to be able to say “I’m working in a ROS environment and this node is running on a real-time system (or embedded device) and that node on a PC...” and not “this part is ROS, another part is X, yet another one Y and the last one Z and these are the protocols between X and Z, and these...” not to speak of the concepts which have to be learned to achieve the latter.
I’d be glad to contribute some useful thoughts (I hope I’m able to provide any :D) and active participation to this group .
All the best,
Ben