I've been working on a robotics project for quite some time. Around the time that I started working on it in earnest I also started learning Elixir. For those of you who don't know, Elixir is a programming language that lives on top of the Erlang virtual machine (called BEAM). Erlang's semantics were designed for Ericsson to run on it's telephony switches. The requirements of massive concurrency, fault tolerance and hot code reloading forced the team at Ericsson to make a bunch of really interesting decisions causing the creation of an immutable, functional language based around a robust actor system, message passing and network-transparent clustering.
Erlang's original creator, Joe Armstrong died early in 2019. The New Stack has a great article summarising Joe's contributions to computer science.
As well as the Erlang language and the virtual machine, Erlang also ships with a massive standard library (called OTP). OTP includes primitives for everything you'd expect in a modern language, and much more.
In addition to the massive boon that is OTP, the advent of Elixir has energised the Erlang community by introducing thousands of new developers to Erlang and it's ecosystem. Elixir keeps the semantics of Erlang and builds on top of them. A new syntax, a hygienic macro system, and modern tooling are just some of the many features that Elixir brings to the table. On top of that, you can still easily make use of years worth of existing Erlang libraries and OTP.
The current go-to for open source (and commercial) robotics is The Robot Operating System (or ROS for short). Despite being branded as an operating system ROS is really just a collection of applications, libraries and tools for orchestrating them together. You can install ROS on pretty much any Linux machine.
The architecture of ROS is based around a few core concepts:
Message Passing - a pub/sub mechanism for the various applications to
send messages to each other or observe the state of other components.
Remote Procedure Call - a mechanism for doing synchronous RPC between
Distributed Parameter System - a shared configuration registry for all
Additionally, the collaboration around ROS has given birth to several key components needed by nearly every robot project:
tf(or "transform") is used to keep track of a
robot's geometry. It is used to track the locations and coordinate frames
of all parts of the robot including sensors, bodies and actuators.
URDF(or "Unified Robot Description Format")
is an XML dialect which is used to describe the physical properties of the
robot. This is used by pretty much every part of ROS (including
understand how to simulate or manipulate the robot.
rvizprovides a 3D visualisation of sensor
data, combined with the robot's URDF information.
Whilst I think that ROS is a pretty amazing tool, it's also fair to say that there are some valid criticisms. Due to it's nature as a specification for the loose-coupling of components it can be difficult to find documentation or guides for new users. I also found it is difficult to work with a ROS project unless you do your development on a Linux machine.
Looking at the list of ROS core concepts it seems like Erlang has these covered (and more). In fact a number of them are covered by the single
Registry module in the Elixir standard library.
- A robot kinematics library. I have been on-again-off-again working on
kinematwhich is a solution for translating between reference frames and one day may be able to solve forward and inverse kinematics.
- A URDF parsing and generating library, probably also as part of
- Drivers for lots more sensors and components. I wrote wafer to assist with this.
- Integrations for common tools and libraries, like Gazebo, OpenCV and OMPL.
Whilst ROS solves the problems of actually running a robot system, it doesn't appear to include any solutions for the "the IoT problem" (please correct me if I'm wrong) - remotely managing what could be a large number of systems which are geographically distributed, may be connected via less than stellar network connections and can be powered on and off without your control. How do we deal with issues? How do we deploy new versions of our code? How do we handle software updates for the underlying operating system?
This is a problem that is underestimated by almost every team that builds these types of edge-computing systems. I've seen it go wrong first-hand. It's such an important problem to me that I took a job at Balena to help solve it.
A lot of work has gone into making Elixir a first-class choice for embedded systems. Specifically the Nerves Project and Elixir Circuits teams have done a heap of work making sure that ARM-based single-board computers (like the Raspberry Pi and BeagleBone) are well supported - not just as Linux devices that Erlang can run on, but also with easy access to hardware, like I²C, SPI and GPIO.
Nerves also includes support for remote development, firmware flashing and over-the-air updates. Recently, with the addition of NervesHub, they've started attacking some of the problems of fleet management too. It's an exciting time to be excited about Elixir and IoT.
I have a vision of a modern robotics toolchain, built using Elixir, with new and emerging IoT tools at their base. Not just for hobbyists, but for commercial robotics product developers too. I hope I have succeeded in sharing that vision with you and that you're just as excited about it as I am. If you can help, that'd be amazing.