@bbfrc/drivethru
v1.2.0
Published
TCP based API/Abstraction Layer for communicating with Firmata based firmware
Downloads
4
Readme
drivethru
A TCP based API for interaction with Firmata based firmware (and also other kinds of robots!)
Getting Started
Install Drivethru using npm
:
As a dependency in your project: npm install --save @bbfrc/drivethru
Or globally (to make use of the default server application): npm install -g @bbfrc/drivethru
Overview
drivethru
is an abstraction layer, sitting between physical hardware and clients that want to interact with said hardware. It is composed of 2 parts, the Robot Controller and the Protocol Server. Together, these allow a client (using the correct protocol) to control actuators and read sensors over a TCP connection.
Robot Controller
The Robot Controller talks to physical hardware over a serial connection, using the Firmata protocol. The RobotControllerBase
class provides an abstract class that exposes/documents most of the functionality of a Robot Controller. In this package, a concrete RobotController
class has been implemented that communicates with Firmata based firware over serial. A DebugRobotController
has also been implemented that simply logs all requests sent to it.
DebugRobotController
The DebugRobotController is set up to echo all operations performed on it, as well as generate an alternating true/false
signal on digital port 0. This can be used to exercise hardware interface clients.
Protocol Server
On the other side of this layer site the Protocol Server. This is a TCP server that takes in commands from remote clients and emits appropriate events. The commands are implemented as FlatBuffers, with the definitions located in the schemas/flatbuffers/
directory of this repository.
FlatBuffers Messages
All messages that the Protocol Server deals with are defined in the drivethru.fbs
file in the schemas/flatbuffers/
directory. This file contains all message types, as well as a wrapping Envelope
type that is used to tell endpoints what kind of message is being sent.
Packet Structure
Since FlatBuffers messages do not include packetization (they are just raw byte buffers that encode a given message type), we cannot simply send them directly over the wire. Thus, prior to transmission, the message buffer is wrapped in a packet. The structure of this packet is as follows:
| Byte | Value | |------|----------------------| | 0 | 0xDE | | 1 | 0xBE | | 2 | Payload Length (MSB) | | 3 | Payload Length (LSB) | | 4... | Payload |
Each packet consists of a 2 byte header 0xDEBE
, followed by 2 bytes indicating the length of the payload (in big-endian), and the payload. All clients that interact with the hardware interface need to follow the packet structure outlined above.
Package Contents and Applications
The drivethru
package can be used both as a dependency in your application, as well as a standalone server application for the most common use case.
Use as a dependency
First, run npm install --save @bbfrc/drivethru
to add this as a dependency to your project.
The package exposes several objects of interest:
RobotControllerBase
: An abstract class that represents an interface to robot hardware. All robot controllers that are used indrivethru
should extend from thisFirmataRobotController
: An implementation ofRobotControllerBase
that communicates with a Firmata based robot, connected over serial.DebugRobotController
: An implementation ofRobotControllerBase
that prints out values that it is sent. It also toggles digital port 0 between high/low once a second.DrivethruServer
: Server module that handles TCP FlatBuffers communication with clients and passes messages to/from a providedRobotControllerBase
object. This takes care of all network communication, leaving you free to focus on building out customRobotControllerBase
classes.
Additionally, the package also exposes the underlying types used for communication. You can find type definitions of these in the protocol-types.ts
file in this repository.
To use the DrivethruServer
, first instantiate a subclass of RobotControllerBase
, and then hand it into the constructor of the server. E.g.:
const server = new DrivethruServer(myAwesomeRobotController);
This will instantiate a new DrivethruServer
that will communicate with your robot. You can also optionally pass in a configuration object to specify which port to use. If none is provided, it defaults to 9001
. E.g.:
const server = new DrivethruServer(myAwesomeRobotController, { port: 9999 });
Once the server is instantiated, you can start it by doing: server.startP()
. The startP()
function will ensure that all the components are up and running, and starts the TCP server on your specified port. The function also returns a Promise
that will resolve once everything is up and running.
Building/Testing
Immediately after cloning this repo, do:
cd <where/you/cloned/the/repo>
mkdir dist
npm install
npm run gen-proto
npm run gen-flatbuf
npm run build
This will set up the output directory, install dependencies, generate the protobuf files and run an initial build
Running Example
The astar-kitchen-sink
example can be run using npm run kitchensink -- SERIAL_PORT_HERE
, where SERIAL_PORT_HERE is the serial port the controller is connected to.
Running
To run the drivethru
program, use npm run start -- -s SERIAL_PORT_HERE
.