I was tired of ROS2, so I rewrote it in Rust

Github: HORUS

Every once in a while, I hear developers complain about how working with ROS2 frustrates them, or students who find the barriers to understanding ROS2 too high. Undoubtedly, ROS2 was originally designed in the lab for the prototyping phase.

However, being widely adopted has turned its design into a messy blob that is not only "thick" - and not in a good way - but also too tangled. Therefore, I came up with the design for HORUS -Hybrid Optimized Robotics Unified System.

At first, I was just experimenting to see whether building a system that respects both the versions and dependencies of low-level packages like drivers, and high-level packages like ML/robotics algorithms would be that hard - unlike in ROS2. Surprisingly, with current modern technology, we can do a lot to make this vision come true. ROS2 users are always looking to avoid "reinventing the wheel" by trying to pick whatever exists in that tangled web and sticking it into their project. This workflow was good, at least in the old days. But now we have AI and modern frameworks/packages, yet developers are still struggling to make them work with ROS2.

My vision is to create a robotics framework that is "thick" as a whole (we can't avoid this - the tools, drivers, etc. make it impossible to be slim and fit everyone's needs), but modular by choice. I mean that developers, similar to ROS2, can still integrate their packages, but in a way that won't require opening at least 10 tabs. The design makes parts swappable - it's like building with Lego blocks, but with easy integration. You don't like this IPC communication mechanism? Swap it with a different IPC framework by editing 1 configuration line, and it won't break. You don't like these environment settings or how upgrading a single package breaks everything else? HORUS solves this.

HORUS aims to provide developers an interface where they can focus on writing algorithms and logic, not on setting up their environments and solving configuration issues. HORUS is designed to be both hybrid and unified. For example:

You can run horus run app.py driver.rs, and Python and Rust will communicate with each other seamlessly, as they all use shared memory for IPC. If a package is missing, the HORUS manager detects it and auto-installs a version that fits your current dependencies.

By design, every HORUS project can be a virtual environment if you want it to be. You can use packages already installed on your machine and link them to your project, or install new ones exclusively in your project. This solves dependency hell and the "works on my machine" problem. We also have horus env freeze, which freezes your environment and provides you an ID that other developers can use with horus env restore - similar to requirements.txt in Python.

I know what you're thinking: don't we already have these features elsewhere? Why not just install them and integrate them into ROS2, like virtual environments or multiple compilers? That's where the unified part of HORUS comes in. Robotics as a whole should be cohesive for the most part. Continuously splitting things apart and then piecing them back together will just create another ROS2. Therefore, by original design, the ecosystem should easily adopt new components and make them native. HORUS has a registry - a database of sorts - that aims to grow by gaining more HORUS packages. This makes future development easier by making every HORUS project part of the ecosystem.

Given all that, a modern robotics framework should have better performance, be high-level, easily integrate with AI/ML, and be user-friendly - even for students breaking into the field of robotics. HORUS is trying to achieve all of this, but without growth in the ecosystem, HORUS would be just another forgotten project.

By the way, you can try it out with the documentation to see the vision and goals: HORUS Documentation

9 Likes

It's sort of refreshing to read a long introduction of a new library/package that isn't ai-slop-ified. No emojis or emdashes or overly emphatic language.

The framework looks good too, but what's the answer to the main advantage of ROS2 (and no doubt the reason people sludge through it): the network effects. Everything is on ROS2. maybe HORUS would be good for a robotics company building from scratch and wanting to finely control every part of it. But who really wants to do that? Is there any plans for something like wrapping ROS packages into the HORUS system?

1 Like

It will be just a matter of time, to re-export standard, common ROS2 packages into HORUS, it will be a better approach than wrapping it, so HORUS won't be too dependent. There will be ROS2 bridge system for HORUS in the future, which letting ROS2 developers to make their nodes, launch files, config files into HORUS with ease. For standardized packages, it is better to create new ones for HORUS marketplace/registry, which contain more modern approaches/frameworks to be used for modern robotics application, while current ROS2 projects can be bridged to HORUS in the future via ROS2 bridge feature.

How complex would be to integrate external Rust package for inverse kinematics? I obviously think should I try to port rs-opw-kinematics.

It will not be integrated strictly like you think, horus environment still use Cargo.toml and horus run still depends on Cargo(building compiler from scratch using rustc will get more trouble in the future for high level parts), but the Cargo.toml file will be hidden, it will be treated as artifacts(kind of lock structures, only for horus run to call cargo to compile). So you can just horus pkg install and horus manager will smart check for its name in crates.io to install inside its local env, or you can decide to have it installed as global, which is a dedicated env of horus in that machine, instead of each horus project like local. For crates.io, and pip packages, horus is wrapping those but the design is to have a dedicated place to put them together, as cache, so .py and .rs can communicate with ease. The packages that need to be integrated or build from scratch might be ros2 packages which are not published elsewhere other than ros2 ecosystem, community.

I only wish you success, but be careful with this. When I — a hardcore C++ programmer who has explored every corner of cmake — started working with ROS 1 back then, one major source of frustration was that although it kind of used cmake, it also introduced tools like catkin and later colcon. These were supposed to simplify things, but instead, they created extra problems when I tried to integrate my existing CUDA application that also relied on cmake.

On top of that, syntax highlighting, code completion, and debugging didn’t work properly in my IDE, which had no idea what this “catkin” was. Things have improved since then — CLion is now a good tool for ROS — but we risk repeating the same cycle.

Rust still isn’t well supported in ROS; the integration is complex, and there are many abandoned crates lying around. If we want to take that niche seriously, I’d build everything around cargo instead.

2 Likes

Thank you for the advice! Really appreciate it! I will take a notice, as I'm also working on C++ API and its build/compile system, and at this point, I wouldn't confidently say that C++ will be integrated, I will make sure all edge cases and tests be passing on UX perspectives, if HORUS gonna break just by adding layers, that beats the purpose of creating it. The only reason I think of adding C++ are for the old drivers packages that seems not to have other languages being provided by the vendors, other than C and C++. Nevertheless, I will make sure HORUS maintain its user-friendly characteristics, even if we have to trade.

At first glance, your project looks to have a similar motivation as
copper-rs. Although, copper seems to pursue more ambitious goals (e.g., ROS2/DDS interfacing).

I think it would help me (and possibly others) appreciate your effort even more, if you pinpoint the differences with Copper as you see them.

2 Likes

Well, our main goal is to facing ROS2 and exceed it as well. I can list the differences between Copper and HORUS:

  • API: copper using tasks and graph ticking, we kept the the transferable API structure from ROS2 for developers to felt easily welcomed, meaning nodes,topics, scheduler is treated like launch file.

  • Copper, is an SDK, meaning they will have more of tool kits, using Zenoh and Iceoryx2 as IPC, (Their default is single process only, which might not be ideal in lots of sophisticated robotics application or prototyping), and they are likely using existing infrastructure. HORUS is a framework, similar to ROS2 originally, and its kind of built from ground up, has its own dedicated structure of shared memory, IPC runtime/ multi-process system(Hub for MPMC, Link for 1P1C) if other tools fit in the design, we integrate them as hybrid. If not, we would rather build from scratch again.

  • We are obsessed with real time more, you can look at the benchmark, normally data types in an IPC system kept around under 100ns, and we are trying to pursue that for robotics messages data types. We are willing to trade WAN communicating for swam robots to pursue the shared memory of a single robot more, meaning we will likely keeping this structure of shared memory as main IPC, WAN communication will be a hybrid approach, meaning we will separate them as communication mechanism for any nodes developers want, not integrate fully like ROS2. This is to focus on dedicating to low-level shared memory for real time control. The goal is to keep this current nodes and pub/sub design and still be applicable for real-time critical robots(in these areas, ROS2 are just prototyping phases, not production)

  • Ecosystem Motivation: We aim to improve by gaining in ecosystem as well, meaning a dedicated marketplace, where all HORUS project unified, so this will prevent the scenarios of nowadays where ROS2 packages are everywhere and don't have their own discover channel other than the forum, community, discussion.

  • We would focus on developer experience more, means we are willing to trade everything to pursue that, if later on, any robots need parts that will break this principle, we would rather add as outer package to be used, but not integrated strictly in our system. You can look at the API, they are very idiomatic.

There are lots of more details or listings I can do to differentiate, there are features that Copper is definitely a better choice today, compared to us - we are alpha and under development. But sum up, Copper positioned themself as like set of tools to build applications, like game engine to games, while we aim to be everything of infrastructure and ecosystem(beside the OS of course) the games rely on to keep existing - system design, low-level runtime, linking packages, development tooling, deployment infrastructure, marketplace, multi-language.Our vision is become the standard system that can be extendable from low-level(hardware, driver, kernel) to high level(algorithms, AI/ML) that every robots stand on, which means outside the scope of just middleware.

2 Likes