-
Notifications
You must be signed in to change notification settings - Fork 1
A hacker's guide to SMCE
SMartCar Emul is an attempt to provide a development tool for the SmartCar platform as well as similar Arduino-based RC vehicle platforms. Its direct intent is to allow users to run their Arduino code against a virtual RC vehicle.
SMCE uses a lightweight game engine, Urho3D, to render a 3D world in which the virtual RC vehicle is placed, alongside a user-controlled camera providing a movable view inside the virtual world. To run the user-code, we first compile it into a shared object with whatever host compiler CMake selects (the ENV passed to our CMake invocation is the same as the one passed to SMCE, so you can still use CMake's environment variables). This however is not doable straightaway with Arduino sketches, since they need the following preprocessing to be turned into C++ files:
- Prepend the line
#include <Arduino.h>
- Expand all C++ preprocessor directives
- Generate function declarations from all the definitions and place each of them before any of their use.
We have tried using arduino-preprocessor
to do that for us, but we have run into major issues where the tool would not work as expected on Windows and macOS, on top of requiring us to force the installation of the Ninja build-system on Windows (since ardpp uses an LLVM compile_commands.json
and CMake can only generate these with the Ninja and Makefile-based generators).
Instead we opted to use arduino-cli
's compile preprocess
command. SMCE uses a CMake script to detect whether ArduinoCLI is installed, and installs it if necessary.
At the time of writing, the current default triplet for compiling sketches is arduino:avr:uno
. Even if you use a different platform, such as the ESP32, we recommend against changing that triplet.
SMCE includes its own implementation of the Arduino functions. The ones that deal with IO have access to an instance of a BoardData
object, which is used to interact with the rest of the system.
SMCE distinguishes two contexts:
- The engine context (because the engine runs inside of it)
- The board context (because the user-code runs inside of it)
The engine context includes the main thread, and manages both the UI and the RC vehicle.
The board context is a single thread which executes the setup
and loop
functions of the sketch as well as an internal init
function exposed by SMCE's arduino library implementation. All three of these symbols are exposed with C linkage. They are accessed by using Boost.DLL
on the shared object resulting from the sketch compilation.
Attachements are also commonly called "backend drivers" among the SMCE core devs; they are scene logic components attached on the vehicle which can subscribe to Urho3D events and have access to the board_data during construction.
They are used to implement the engine-facing part of the fake devices, such as the sensors and motors.
For I2C devices, the contents of the reg_moniker
module can be used to simplify the logic; see existing I2C devices for how to use them.
If you want to add a new kind of sensor on the car, say implement the odometers that SmartcarShield supports, this is where you will put most [if not all] of your time into. Note that we will happily accept PRs adding support for new attachements, especially if the Arduino code that drives it does not need to be rewritten and the common ones on the Arduino library manager can be used directly (an example of that is our partial support for the VL53l0X).
The runtime library consists of the ardrivo
module; it is compiled as a shared library (DLL on Windows), so all exports need to be marked by SMCE__DLL_RT_API
.
To add functionnality to the Arduino runtime, such as adding the SD
library, add the header (i.e. SD.h
) under /include/ardpolyfills/
, and put the sources in the ardrivo
module. You can assume that board_data
will be a valid pointer even at dynamic initialization if you have called maybe_init()
. If your library uses GPIO pins, you should check against board_info
to see whether the pin has the correct capabilities set.
Just read it; it is not yet written properly to be easily extended; this will be coming soon as we too want it to be more accessible for ourselves. Ask @AeroStun directly for specific steps to take in order to add functionnality to the CMake scripts.
ItJustWorks™