RC Viper ACR - Viper 1.0 part 1
The new part of RC Viper ACR Technologies & Systems shows version 1.0. This is the part one from two.
After several Alpha and Beta versions, we’ve created a version of the program called Viper 1.0. In this version, the application design was inspired by the Uconnect system, which is used in real Dodge cars.
This version is fully functional and tested in the model. It includes both automatic and manual control of aerodynamics, telemetry in miles or kilometers per hour, control of lights, engine sound adapted to real speed with adjustable volume, loading and storing variables when the model is turned off. It’s fully responsive, so we can use it on computers as well as on mobile phones, it also supports live cross-browsing, which means that when we change some setting on our device, it changes on all connected devices, so we always have the latest information from model.
Used resources and libraries
We needed several files and libraries to create a complex web application.
We used the Bootstrap elements, we downloaded .css, .js and font files on the official site https://v4-alpha.getbootstrap.com/getting-started/download/. We also needed jQuery, we also downloaded it from the official https://jquery.com/download/ site.
Instead of the classic slider we used noUIslider because the classic HTML slider does not work properly as a DOM element. Those files we downloaded at https://refreshless.com/nouislider/download/.
To show telemetry, we used in first version this speedometer version from http://www.jqueryscript.net/form/Creating-An-Animated-Speedometer-with-jQuery-CSS3.html.
We also incorporated the live display of lights on rotary models, which is used in version 2.0, we’ve downloaded it from the github https://github.com/heartcode/360-Image-Slider.
After opening the page, we are on the startup screen. This part of the page works with the start.py program. When you click on this screen, a request to send the current data is sent to start.py. The program checks if the model is started, if not, it loads the latest aerodynamic configuration and volume from the firstload.info file, then sends it to the page that displays it. If the model is started, additional information about the current setting will be sent in addition to this data. If the page opens in mobile in the portrait view, it asks you to rotate the device and then display the startup screen.
Starting, Running Programs
When you click on the Startup screen, the page moves to the telemetry section. It is not active as most of the features unless we have started the model. Therefore, we move to the engine start and control section. The start button is a checkbox that we have modified in controllers.css. We created a label for this checkbox based on the image engine_button-off.png. If the checkbox is unchecked, the background of this image is set to red, orange on hover, when green is selected. We also set the change of the click position, which produces the push of a button. Sending a message after clicking on it is the same as the Alpha version. The Channel for sending the status of this checkbox is called “start”.
When start.py captures a message on this channel, it checks the status of the checkbox to see whether the model has just started or shut down. If the model is just starting, the sub-programs auto.py, led.py, telemetria.py and engine_sound.py are running. Subsequently, the necessary data is sent to these programs, for example, if the manual aerodynamic mode was selected at the last shutdown, a message containing the selected mode and setting of individual elements via the respective channels to auto.py or its remote.py subprograms, which mediates manual servo control , which uses this last setting and sets the servos to the desired position. If the model is switched off, these subprograms are closed, the GPIO pins are cleared, the rear wing is retracted, and the necessary data is stored in the firstload.info file.
In the engine start section, we also find the engine volume control. V10 engine sound is telemetry data management, depending on whether the car is accelerating, decelerating or other sound is playing. We used pygame.mixer to play it. Pygame plays audio in .ogg format. In the RPI reduction we’ve connected the 5W Speaker Defender Mono as the audio output. At the beginning of the program, we created rpm, volume and last_sound variables. Next, we determined the size of the buffer, mono or stereo, we used the recommended setting for RPI, then it is possible to start the mixer. It is then possible to load audio files into variables.
The program takes data from telemetry flowing through the rpm channel. When capturing data, rpm_callback starts the process of evaluating these data. It compares the new engine speed to the last one, at the same time verifies the last played sound, accordingly releases the sound in the infinite loop, stops the last played sound and returns the received speed and now plays the sound in the program. This is repeated every time you accelerate or slow down.
We used the nouislider to control the volume. In the HTML code, we created a slider ranging from 0 to 100, adding input and display values, and buttons to increase, decrease, and turn off the volume. The slider sends data to the server, the buttons and the input control the slider. Inside input is the value displayed in %. The slider sends data only after the mouse has been dropped or the touch screen has been terminated, so it does not burden the network unnecessarily. The buttons used bootstrap glyphicons, the design of the input and the slider is set in controllers.css.
Engine_sound.py captures the data sent from the page, changes the number of decimal places to the required value and adjusts the volume for all the used sounds. At the end of the program, we see the first volume setting, on start up the start.py volume stored in firstload.info, when this volume is captured and set, the first sound is played once, which is the startup of the engine.
Telemetry detects rpm that it transmits to the application in real time, these datas are converted to speed and displayed on the tachometer. Telemetry also sends these rpm to engine_sound.py, which controls the sound of the engine. In-app speed is available in miles or kilometer per hour.
GPIO pin 13 is set to input as in the Alpha version, and we set it to watch when logic 1 appears. Logic 1 will appear when the reflective optocoupler is turned on, which detects the engine speed. The program runs while loop, which counts the turns of engines per second, and sends the result through the “rpm” channel. To reduce network load, the data is sent only when it does not equal the previous result, ie the program does not send unnecessarily zero when the model is stopped.
In the HTML code, we created two speedometers, one for rpm and one for speed. Next, we’ve created a speed indicator in numbers and a km/h or mph switch. We used the dashboard from the real Viper on the background.
On the left of the tachometer there is a button to switch between km/h and mph. Again, this is a classic checkbox with an altered design. After clicking on it, the KMH digital pointer changes to MPH. PubNub checks whether the checkbox is ticked and calculates the speed in kilometers or miles from receiving a telemetry message.
On the right below the speedometer is a digital display of speed in numbers. It is a classic HTML <h3> element that displays the calculated speed.
Control of lights
Lights on model are controlled simply by checkboxes with changed design. The data is sent as in the Alpha checkbox. After clicking, the status of the checkbox will be sent to the led.py program, which will evaluate the received data and set logic 1 to the corresponding GPIO pine. This will cause the opto-coupler to switch on the light module’s interface board, which will close the circuit of selected LEDs.
To turn on the indicator, a subprograme is run in place of direct GPIO control, with an endless while loop, which turns on and off the optocoupler at half-second intervals. This will ensure the flashing of the indicator. Turning the indicator off closes the subprograme and sets the GPIO to 0 so the indicator does not stay on.
On the right of the screen we will find a live view of the lights. Here is a rotating 3D model script used, but in this version of the program rotation is deactivated and replaced by static display.
Basically, this script can load a series of images that, by dragging the cursor, change their views, are hidden or visible. We needed to edit it to display several layers of images, one layer for each light. Each layer changes the display depending on whether the lights are turned on.
First, we created the variable imageNameX for each layer of light, where X indicates the layer number into which the model images were loaded from the illuminated lights. We wanted the layers to rotate at the same time as the background that is loaded into imageName and included in the variable image that provides rotation. For this reason, we’ve added layers to the variable image instead of creating new variables. We also needed to separate the layers from each other, so we added to the class the light-imageX layer, where X indicates the layer number. After the layers have been added, we have set the number of images in array, in this case 1, because the rotation is deactivated in version 1.0.
Now, only a script has to be created for each layer, which will show it after clicking the appropriate checkbox and hide it when it is unchecked. This is how we created a real view of the lights on a 3D model.
This is all for today, next time really interesting topic – aerodynamics. Stay tuned and have a nice day!