We currently use Firbre as the main method of communicating between the Python tools and the ODrive. This has many good features, but it is not that mature, and there could be some risk associated with proceeding with Fibre instead of some more established protocol. Hence I would like to take the time at this stage to re-evaluate what the roadmap in terms of communication should be.
Vision for ODrive
Let me start by giving the picture of how I see the priorities:
Compatibility with existing standards.
Where it makes sense, it would be nice to be able to plug-and-play with existing systems. Supporting ubiquitous existing standards makes this possible. Examples are G-code, step/dir/enable, basic ascii position commands and maybe even (a subset of) CiA 402. Note that these are protocols that exist “on the side”, and are not the native protocol of the ODrive: I guess the point is that whichever we use as the native protocol, it should be capable of coexisting on the ODrive with these other ones.
Easy to change, remix, prototype and develop with.
I have no problem sacrificing a bit of memory footprint, bandwidth, CPU-time etc, to gain a protocol that is extremely plug-and-play: between nodes, between vendors, between hardware platforms.
It should be completely automatic and with short turnaround time to add or change a message.
The ultimate aim is to have the machinery to very easily add some definition in a single place, and then you can automatically get a float somewhere in firmware memory, along with sensible ways to refer/interface to this float, and the ability to spawn a slider in a GUI for playing with this float.
One day we use USB, another we use UART, or CAN, or Ethernet, or communication lasers.
We don’t necessarily demand that this exists already for stm32, but it is important that it should be fairly straightforward to add.
Maintenance and support
ODrive Robotics is extremely resource limited. We are not Google, Apache or Mozzilla, we don’t want to be in the business of maintaining protocol standards. Any and all reuse of existing actively maintained implementations is very good. This doesn’t mean that we will be able to just point our finger at an existing protocol and hope that it will work: we may need to do some legwork to get it suitable for use with ODrive. But ideally we do some integration work that we try to keep as simple as possible, and let someone else maintain the rest.
This is somewhat related to the above: We want to maximise the chance that someone else has already or will write a module that supports the protocol, then we get compatibility for free.
Example: Some completely unrelated entity may write a general gprc or Thrift interface module to ROS, but not so much a less popular one.
An RPC protocol
To easily implement a decentralized robotics architecture, it’s much more valuable to be able to seamlessly call, invoke, signal and query the remote objects, code and functions, rather than just plainly sending around data by itself.
As noted above, the machinery required to expose/translate calls should be as automated as possible. Similar to how in Fibre we can easily point to a C++ function and it’s automatically exposed to Python. Or in other protocols like grpc, you specify the arguments/return/name of the function, and interfaces are generated in both languages.
Evaluation of Fibre today
The vision behind fibre is very aligned with the vision for ODrive, so it’s no surprise that even in the currently fairly immature state, it does a very good job. I can point a finger at some data member or function on the ODrive firmware, and it appears by sheer magic in Python. And this is without having to distribute some schema to anywhere, or regenerate code, or anything.
On the other hand, there is no client side implementation for ODrive, there is no facility to initiate transfers on the ODrive’s initiative (subscription), the latency and bandwidth seen on USB has lots of room for improvement, the density of TODO is immense, I happen to know that some parts were whipped together very quickly, the testing is limited, and the only people testing it are ODrive users. In other words, it is very not mature.
Exacerbating this is the fact that it is all written by @Samuel, who no longer works at ODrive Robotics. So when there are issues, it’s very painful for me because the burden falls on me to fix it. While I am fully capable to dig into the meat of this kind of stuff, I don’t have the time or resources to do so: I need to focus on ODrive’s core features and product oriented stuff.
Use something established?
The alternative would be to integrate with some established RPC standard. Maybe it doesn’t align as precisely with the vision of ODrive, but it would be a lot more mature and have other active maintainers. Other people to hit bugs first, and smaller chance of issues that require me to deal with them.
The idea would be to spend some focused effort integrating it with ODrive, and then the maintenance burden would be a lot less from then on. Importantly, we can still contribute or add pieces we need to the existing standard, rather than recreate everything. Basically avoid this:
Some things I found
I had a very brief look around to see what might be suitable, and the most appropriate thing I found would be to add a USB transport to grpc using nanopb. There are others who seems to have expressed interest in communicating grpc to microcontrollers, including over USB.
Of note is also Apache Avro, specifically it’s self-describing shema-exchange handshake.