# Augie Hello, and welcome to my robotics project. Augie is (or will be) a large hexapod robot. It is an exercise for me to learn (or in some cases relearn) the skills needed for building and developing robots. ![render](https://gitlab.com/jimsy/augie/raw/master/images/render%20oblique.png) ## Platform Augie is designed in [Fusion 360](https://www.autodesk.com/products/fusion-360) and the latest full assembly is available for download [here](https://a360.co/2n5Bhzm). Most of the robot platform is CNC cut out of flat plates of 3mm acrylic (although I'd love to use aluminium in the future) with joining parts 3D printed. Parts are sized to fit within the work area of the commonly available "3018" hobby CNC router. They include 3.5mm t-bones to make it easier to mill slots with a router, but should be fine to be lasered too. Be aware of your kerf though - I haven't accounted for it in the design. Recent versions of the STL files needed for printing are kept in this repository, but I can't guarantee that they're completely up to date. Best to generate them from the Fusion 360 (it's free for hobby use) archive where needed. The bot is designed around [DSSERVO RDS5160 HV 270ยบ](https://www.banggood.com/DSSERVO-RDS5160-HV-180270-60kg-Metal-Gear-Dual-Ball-Bearing-Digital-Servo-For-RC-Robot-p-1542158.html?ID=6266225&cur_warehouse=CN) servos, which should provide more than enough torque for the robot to execute any task I can teach it. Currently it uses 19, although I think this will increase to 21 in the next version. I've tried my best to standardise on M2.5 hardware where possible, with the majority of the screws being M2.5x6 socket hex head screws. This was largely chosen due to the available mounting holes on the servos. The electronics (KiCad files in this repository) are based around two Raspberry Pi Zero W 1.1's running [balenaOS](https://www.balena.io/os/) talking to a number of peripherals. Current peripherals include: * 2 x [DS3231](https://www.adafruit.com/product/3013) each Pi has it's own real time clock because a computer without an RTC just seems wrong. * [PCA9641](https://www.nxp.com/products/interfaces/ic-spi-serial-interface-devices/ic-bus-repeaters-hubs-extenders/2-channel-i2c-bus-master-arbiter:PCA9641) arbitrates between the i2c busses on the two Raspberry Pi's granting access to the downstream peripherals to only one at a time. * 2 x [PCA9685](https://www.adafruit.com/product/815) two 12 channel PWM drivers allowing us to drive up to 24 servos. * [BNO055](https://www.adafruit.com/?q=bno055) 9-DOF IMU which contains accelerometers, gyroscopes and magnetometer and performs it's own sensor fusion. * [MPL3115A2](https://www.adafruit.com/product/1893) barometric pressure, altitude and temperature sensor. * [INA219](https://www.adafruit.com/product/904) high side DC current and voltage sensor. Provides information about the status of the batteries. * 2 x [1.3" 128x64 monochrome OLED displays](https://www.adafruit.com/product/938). * [MCP23017](https://www.microchip.com/wwwproducts/en/MCP23017) 12-bit i2c I/O expander. Planned future improvements include: * A GPS module of some sort. * Contact sensors for the feet. * LIDAR or ultrasonic distance/object sensing. * Moving from "breakout boards" to a properly designed PCB. * A mobile data connection. * Solar charging. ## Software Augie is written in [Elixir](https://elixir-lang.org/) because I believe the [Erlang](https://www.erlang.org/) virtual machine (named [BEAM](https://github.com/happi/theBeamBook)), which Elixir runs on is an excellent platform for robotics. The key relevant features of Erlang (and thus Elixir) are: * **Concurrency** one of the main primitives in Erlang is the process. Processes are lightweight and transparently scheduled across all available CPU cores by the BEAM. The virtual machine can handle massive numbers of processes without problems, even in severely resource constrained environments. This concurrency gives us the soft-realtime features we need to respond to sensor input in a timely fashion while still orchestrating the robot. * **Network Transparent Clustering** instances of BEAM can be connected together, either on the same machine or across a network. The location of a process is transparent to other processes sending messages to it. This provides for both horizontal scalability and redundancy. In our case redundancy is more important. * **Resilience** [the actor model](https://en.wikipedia.org/wiki/Actor_model) is baked into the core of Erlang allowing processes which fail to be restarted with known-good state. Erlang calls them supervisors, and they truly are the backbone of Erlang's reliability. Additionally Elixir brings many new features to the table including; meta-programming via a hygienic macro system, modern syntax and tooling and the [Hex](https://hex.pm/) package manager. As well as this repository there are a number of other projects related to this one: * [ssd1306](https://gitlab.com/jimsy/ssd1306) an Elixir-based driver for interacting with the driver on the 128x64 pixel OLED displays. * [vivid](https://gitlab.com/jimsy/vivid.ex) a simple 2D renderer capable of rendering shapes and text into a buffer. * [pca9641](https://gitlab.com/jimsy/pca9641) an Elixir-based driver for the PCA9641 i2c bus master arbiter chip. * [pca9685](https://gitlab.com/jimsy/pca9685) an Elixir-based driver for the PCA9685 PWM driver. * [mpl3115a2](https://gitlab.com/jimsy/mpl3115a2) an Elixir-based driver for MPL3115A2 barometric altimeter. * [ina219](https://gitlab.com/jimsy/ina219) an Elixir-based driver for the INA219 current and voltage sensor. * [angle](https://gitlab.com/jimsy/angle) an Elixir library for converting between angles in different representations. * [kinemat](https://gitlab.com/jimsy/kinemat) an Elixir library to provide forward and reverse kinematics of robotic systems (needs help!). * [ease](https://gitlab.com/jimsy/ease.ex) an Elixir library to provide easing functions for animation or motion. * [balena_device](https://gitlab.com/jimsy/balena-device) an Elixir library to interact with the Balena on-device supervisor API. * [balena-erlang](https://gitlab.com/jimsy/balena-erlang) container builds of recent Erlang versions on top of the [Balena base images](https://www.balena.io/docs/reference/base-images/base-images/). * [balena-elixir](https://gitlab.com/jimsy/balena-elixir) container builds of recent Erlang versions on top of the [Balena base images](https://www.balena.io/docs/reference/base-images/). Using the `balena-erlang` containers. ### Cluster Operation The serial interfaces of the two Raspberry Pi's are physically connected together and create a private IP network between them using PPP. This functionality is described in the `ppp` service of this project's `docker-compose.yml`. If you're using different versions of Raspberry Pi you may consider just connecting the ethernet interfaces together with a crossover cable and modifying the compose file accordingly. We use the [`mdns`](https://hex.pm/packages/mdns) package to create an mDNS server on the PPP interface and advertise our availability as a potential Erlang cluster. We do this because the IP address of the PPP interface is randomly generated and will change each time the interface is brought up, and also because the system doesn't know ahead of time which (of the potentially many) devices associated with this [balenaCloud](https://www.balena.io/cloud/) application have been paired in this robot. When a new peer is detected it is added to the cluster via [`libcluster`](https://hex.pm/packages/libcluster). The distributed registry is managed by [`syn`](https://hex.pm/packages/syn). Implementation details in [`MdnsInterfaceWatcher`](https://gitlab.com/jimsy/augie/blob/master/augie/lib/augie/mdns_interface_watcher.ex) and [`MdnsClusterStrategy`](https://gitlab.com/jimsy/augie/blob/master/augie/lib/augie/mdns_cluster_strategy.ex). ### Software Updates Software updates are deployed using the `balena push` command of the [balenaCli](https://www.balena.io/docs/reference/cli/). We use the [update locking](https://www.balena.io/docs/learn/deploy/release-strategy/update-locking/) feature of balenaCloud to ensure that only one Raspberry Pi in each pair is updated at any given time. This ensures that there is always one device able to orchestrate the robot, even during software updates. Additionally, in the event of a net split both devices will lock updates to ensure that they cannot be restarted because they cannot be sure they're not the only one available to run the robot. The lock can be overridden in the balenaCloud UI if required. Implementation details in [`UpdateLockManager`](https://gitlab.com/jimsy/augie/blob/master/augie/lib/augie/update_lock_manager.ex). ## Licenses All physical design artifacts (CAD designs, STL and DXF files, etc) are license under the [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-nc-sa/4.0/). All software code is licensed under the terms of the [Hippocratic License](https://firstdonoharm.dev/) version 1.2 or later. The text of which is provided in the `LICENSE` file in this repository. The copyright owner for license and all other purposes is James Harton, [james@harton.co.nz](mailto:james@harton.co.nz). For the purposes of attribution it is sufficient to link to [this repository](https://gitlab.com/jimsy/augie).