Our goal is to make a group of five cars drive synchronically and make some shapes while driving.
The cars are controlled by a NodeMCU component, which can communicate with the computer through Wifi.
The cars are made from a plastic board and uses 5V battery.
We track the cars in real time with Optitrack cameras system.
The code for the NodeMCU component is in arduino. We used the Arduino environment to write it. Here is a link for the Arduino code
The main code, meaning the interface of the commands for the cars and the show code, is in C++. We used Visual Studio 2015 as a prigraming environment for it. Here is a link for the C++ code
* The computer communicates with the cars through Wifi.
*The cars move synchronically and with no “dilay”.
* The cars make beautiful shapes.
In order to create the show, we had to work in two different planes: building the cars and writing a low-level code in Arduino to control them; writing a high-level code in C++ to synchronize the cars movements and create the show.
Building the cars and working with the Arduino:
We used cars which were developed by Yair Marom, and we changed them according to our needs. Each car is built from a plastic board and two DC motors, which are connected to two big wheels. Another small wheel is placed at the front of the car, this wheel is free to rotate 360 degrees and it helps the car to rotate right and left. The wheels are controlled by a DRV-8833 controller:
And here is a scheme of the component and the connections to it:
We chose to control the cars by a NodeMCU component instead of an Arduino board, because the communication in real time with the NodeMCU is more comfortable and it is possible through Wifi. A nodeMCU:
And here is a scheme of the component:
The NodeMCU is connected to a battery (5V) and it provides the voltage to the DRV8833. This is the car:
The car is moving according to the commands we send to the NodeMCU through Wifi. We wrote an Arduino code which enables the user to write the command (move forward or beckwards, turn left or right, stop and more) in an http browser, then parses the commands and make the car do what the user wanted (there is a link to the code upper).
Writing the C++ interface and main code:
We then wrote a wrapper code to the Arduino code, in C++. The wrapper code was aimed to supply a comfortable interface for sending the comands to the cars, and make them move synchronically. At this point we started using the Optitrack system. This is a set of special cameras which can follow objects’ motion in real time. Markers are sticked to the objects and the cameras track them. The software we used in order to see the cameras output and to manage their activity is called MotiveTracker (version 1.8.0). Each car held three markers on it and was treated as a “rigid body” in the MotiveTracker:
The cars in reality:
The rigid bodies in the MotiveTracker:
To get the cars coordinates in real time from the MotiveTracker, we used a code from the Natnet (version 2.10) library of Optitrack. This library includes some samples, meaning codes that returns the user the objects position. We used the PacketClient sample. We designed a multithreaded interface, using the PacketClient code. Our code is based on two main data structures: the cars array and the command queues array. The cars array holds the car objects, and the command queues array holds a queue for each car. The commands that are sent to the car are inserted to its queue. The system works with 5 threads: client thread, meaning the thread which updates data, updates each car position (coordinates and angle) while driving (in real time); and 4 execute threads, one for each car, which goes over the car command queue, pops commands and execute them.
In order to be able to send commands to the cars easily, we wrote a code which enables the user to send commands from this type to the cars: Move(CAR_ID (here from 1 to 5), DIRECTION (forward or backward), NUMBER OF BLOCKS (here, one block size-0.2 meter)) and Rotate (CAR_ID (here from 1 to 5), COMPASS (one of 8 diractions of the compass rose), ANGLE (in degrees)). The commands are based on sending a simple command to the NodeMCU (with the Arduino code burned on it), what makes the car start the motion, and then sending it a command to stop according to the command parameters and the coordinates the Optitrack returns. For example, if we want car 1 to move 3 blocks forwards, the command we need is: Move(1, FORWARDS, 3) and it will send the car a command to move forward, and start to calculate the distance from the current car place to its destination (3*0.2=0.6 meters from the starting point), which is changing every moment. When the car reaches the destination (the difference between the destination and the current place is 0), the code sends the car a command to stop. The commands of rotations are similar
The main code, meaning the code which made the cars do the show (create the shapes) is based on the interface we developed. It uses the commands Move and Rotate and that makes the cars move synchronically. Here is a movie which displays 2 different Car Shows we created (it it possible to create various shows with the commands interface we coded):