S20: Nimble

From Embedded Systems Learning Academy
Revision as of 05:06, 22 May 2020 by 243 user3 (talk | contribs) (Advice for Future Students)

Jump to: navigation, search

Nimble Autonomous RC Car

"RC car Overall looks"
"RC car Overall looks"

Abstract

In this project, an autonomous vehicle framework for an RC car is presented using dedicated ECUs for motor control, on-board LCD display, steering control, sensor information handling, and communication bridging. A mobile application was also developed that allows for a user to set a destination, and receive updates on the RC car's position via a Bluetooth connection to the GPS unit. CAN communication between sensors and ECUs was defined via a DBC file. Code was developed using test-driven design principles in order to lower time spent debugging. Unit testing was performed using the CMock framework.

Introduction

The project was divided into these modules:

  • Sensor node
  • Motor node
  • Driver node
  • GPS node
  • Bridge control node
  • LCD node
  • Mobile application

The objective was to create an autonomous vehicle that could navigate to a given GPS coordinate sent via a mobile application. The vehicle moves towards the target position Using a pre-compiled list of checkpoints, and handles obstacles along the way via its ultrasonic and infrared sensors. Updates on Nimble's position are sent to the mobile application via bluetooth.

Flow chart of RC car module interaction

Team Members & Responsibilities

<Team Picture>

  • Tanmay Chandavarkar LinkedIn Gitlab
    • Sensor Module
    • RC Integration and testing
    • Wiki
  • Yuming Cheng [ LinkedIn] Gitlab
    • Motor Module
      • GPS Module
      • Driver Module (Master Module)
      • LCD display
      • RC Integration and testing
    • Wiki
  • Naeem Mannan [ LinkedIn] Gitlab
    • Wiki
    • Mobile Application
    • Bridge Controller
  • Francesco Vescio [ LinkedIn] Gitlab
    • Wiki
    • Code Review
  • Lawrence Wan LinkedIn Gitlab
    • GPS Module
    • Driver Module (Master Module)
      • Motor Module
      • LCD display
      • Sensor Module
    • RC Integration and testing
    • Wiki


Team Deliverables Schedule

WEEK

START DATE

END DATE

TASK DETAILS

STATUS

1 Feb 2020 4 March 2020
  • Create and establish GitLab repository
  • Establish slack channel and invite Preet
  • Look through previous years projects and study it
  • Distribute major roles among team members
  • Complete
  • Complete
  • Complete
  • Complete
2 05 March 2020 12 March 2020
  • Create a Bill of Materials.
  • Select and order an RC car.
  • Make Repo on Gitlab for all modules - Follow Naming Convention.
  • Making the Wiki schedule.
  • Complete
  • Complete
  • Complete
  • Complete
3 13 March 2020 19 March 2020
  • Select Part Number for Sensors (Tanmay, Ellis )
  • Designing and deciding PCB tool(Lawrence )
  • Finalizing GPS module by doing some research (Yuming )
  • Finalize and order LCD (Francesco )
  • Finalize Motor and Order it (Lawrence , Yuming )
  • Environmental setup of mobile app (Naeem )
  • 3/17/2020 -> Project Lab - RC Car Infrastructure
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
4 20 March 2020 26 March 2020
  • Understand DBC and implement the DBC file compatible with all the controllers. (Updating the DBC files from all nodes)
  • Finish purchasing the Sensor (Tanmay)
  • Establish communication across all the CAN controllers over CAN bus based on the DBC file.
  • Verify the power-up interactions and configurations between Master and the other controllers.
  • Establish a connection over Bluetooth and mobile app.(Naeem)
  • 3/24/2020 -> Project Lab - GPS & Compass Node
  • 3/24/2020 -> Anonymous Reviews
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
5 27 March 2019 09 April 2019
  • 3/24/2020 -> Finish deciding the Pins that will be used in each nodes.
  • 3/30/2020 -> Completed the rough draft of block digram and Flow chart for each node logics.
  • Establish a communication between Bluetooth devices.(Naeem)
  • Interfacing of ultrasonic sensors to the SJTwo board and check for basic functionality. (Tanmay, Ellis)
  • Interface of Servo & DC motor to the SJTwo board and check for basic functionality. (Yuming)
  • Interface Compass module with SJTwo board using I2C serial bus. (Lawrence)
  • Interface GPS module with SJTwo board. (Lawrence)
  • Interface bluetooth module with SJtwo board using serial Communication. (Naeem)
  • Configure bluetooth module name as Nimble using Communication Mode. (Naeem)
  • Add a TextView for displaying the Bluetooth connection status in mobile App.(Naeem)
  • Explore UI designing of LCD. (Francesco)
  • 4/01/2020 -> Updated Overall DBC file.
  • 4/01/2020 -> Update the wiki schedule.
  • 4/04/2020 -> Completed the Circuit designs for the PCB.
  • 4/04/2020 -> Finalized the components for PCB.
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
6 10 April 2020 16 April 2020
  • Implement basic obstacle avoidance algorithm based on sensor data and test the same.
  • Continue testing motor driver via commands from CAN bus.
  • Build in speed steps to reverse motor for reverse to work correctly.
  • Mount all the sensors and test for any dead band and modify their positions for maximum coverage.
  • Integrate the fusion of LIDAR and Ultrasound sensor to get overall feedback from all the directions.
  • Develop algorithm to avoid obstacles and plan the car's further navigation path.
  • Complete final prototype of the obstacle avoidance feature.
  • Calibrate Compass Module. Develop code for Compass module communication over CAN.
  • Test Run the Motors driven by wheel feedback and sensors, Basic obstacle avoidance.
  • 4/16/2020 -> Update the wiki schedule.
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
7 17 April 2020 23 April 2020
  • Configure GPS device baud rate and interface it with SJOne board using UART.
  • Send and receive current location, destination and checkpoint coordinates to and from App and Geo module via BRIDGE.
  • Calibrate sensors readings and work on filtering algorithm with Master & Sensor
  • Begin work on LCD to show vehicle live status(speed, fuel-status, obstacles, distance to destination etc.) in a GUI.
  • Finish implementing speed control on motor (to make sure requested speed is met based on RPM read).
  • Work on Car reversing using Motor Controllers.
  • Integrate all modules with the Master to test the data flow.
  • Validation & Verification of obstacle avoidance, steering logic with rear sensor inputs and reversing.
  • Start incorporating GEO Controller information to Master module Steering logic.
  • Decide, implement and test data exchange between Geo Controller and BRIDGE.
  • Calculate and send simple bearing angle and destination status on CAN to figure out initial challenges.
  • Add a Google Map for setting the car's destination.
  • Send car location to app and check points received to Geo module.
  • Verify the stringent requirement of Start-up Sync, Periodic heart-beat messages.
  • 4/23/2020 -> Update the wiki schedule and the git repo.
  • Not Started Yet
  • Not Started Yet
  • Not Started Yet
  • Not Started Yet
  • Not Started Yet
  • Not Started Yet
  • Not Started Yet
  • Not Started Yet
  • Not Started Yet
  • Not Started Yet
  • Not Started Yet
  • Not Started Yet
  • Not Started Yet
  • Not Started Yet
  • Not Started Yet
8 24 April 2020 30 April 2020
  • Testing & Validation of the LCD UI and display run time vehicle status and looking forward for feedback from team if any.
  • Improve & Validate Navigation logic with multiple checkpoints, bearing angle and destination information.
  • Identify and mitigate GPS locking, Location Accuracy and Number of Satellite-In-View coming.
  • Validate Accuracy of Compass Calibration with iPhone Compass.
  • Determine and add DBC Changes and finalized.
  • Implement the steering logic with bearing angle and status provided by GEO-Module.
  • Consistently Communicate current car location to App, get check points from App and relay them to Geo module.
  • Send additional vehicle status information from can bus to the App for display.
  • Send the request to Google for getting the checkpoints(use the Google Maps Directions API).
  • Field test and check for obvious issues in obstacle avoidance, navigation, maintaining speed (up/down hill).
  • Provide feed backs to each team on identified short comings.
  • Update Wiki with new details and information.
  • DEMO: GPS driving
  • Not Started Yet
  • Not Started Yet
  • Not Started Yet
  • Not Started Yet
  • Not Started Yet
  • Not Started Yet
  • Not Started Yet
  • Not Started Yet
  • Not Started Yet
  • Not Started Yet
  • Not Started Yet
  • Not Started Yet
  • Not Started Yet
9 1 May 2020 7 May 2020
  • FIELD TESTING - CRITICAL WEEK
  • Implement turning indicators, break lights and head light.
  • Check for Corner cases for steering logic under various conditions and locations.
  • Analyse field test results for GPS and CMPS and work on it if required.
  • Test the accuracy of check-points from the Blue-tooth controller, location data from the Geo-controller sensor and Navigation Algorithm.
  • Check overall robustness of the complete system.
  • Establish complete connection on PCB
  • Update wiki with details.
  • Not Started Yet
  • Not Started Yet
  • Not Started Yet
  • Not Started Yet
  • Not Started Yet
  • Not Started Yet
  • Not Started Yet
  • Not Started Yet
10 8 May 2020 21 May 2020
  • All hands on testing and final bug fixes.
  • Check for tuning or calibration of modules if required.
  • Complete end-to-end testing for various scenarios and conditions.
  • Create the semester long project activity video and upload to YouTube.
  • Update and finalize wiki.
  • Not Started Yet
  • Not Started Yet
  • Not Started Yet
  • Not Started Yet
  • Not Started Yet
11 22 May 2020
  • DEMO: Final Project
  • SUBMISSION: Final Project Wiki
  • Not Started Yet
  • Not Started Yet

Parts List & Cost

Item# Part Desciption Vendor Qty Cost
1 RC Car Traxxas - Amazon [1] 1 $168.84
2 CAN Transceivers MCP2551-I/P Robotshop [2] 6 $ 6.00 per unit including shipping fee
3 GPS & Antenna Amazon [] 1 $ 78.24 including shipping fee
4 Compass Amazon [] 1 $ 41.48 including shipping fee
5 Ultrasonic sensors(LV-MaxSonar-EZ0) SparkFun [3] 1 $ 29.95
6 Ultrasonic sensors (LV-MaxSonar-EZ1) SparkFun [4] 2 $ 51.90
7 IR sensors (GP2Y0A21YK) SparkFun [5] 1 $ 34.23 including shipping fee and tax
8 PCB Fabrication JLCPCB 5 $ 39.13 including shipping fee and tax
9 IR Optocoupler Amazon 5 $ 40.01 including one day shipping fee and tax


Printed Circuit Board

Design and Architecture

The PCB made for the Project Nimble RC car was initially designed in EAGLE, however, due to the board size limitations, the PCB had to be designed using DipTrace instead. This design was the first and only iteration in designing the layout of the PCB. The design of the PCB was designed around the four SJTWO LPC4078 micro-controllers required for us to use for the project, the DRIVER, MOTOR, GEOGRAPHICAL, and BRIDGE/SENSOR nodes. The PCB layout consists of four through-hole "slots" where the controllers will be connected (with respect to the controllers' orientation and ports/pins) to the PCB. The power section includes a USB socket as well as a through-hole mount for a LM7805 regulator. Through-hole header pins are also included for the components needed for their respective controllers such as the sensors, LCD, GPS, Compass, etc.. LED circuits were added to provide visual information for the user to indicate the motor and servo motion states, as well as to indicate if a sensor has detected an object. Lastly, the design for the CAN bus includes the connections needed for power, RX/TX, and the CAN low and CAN high bus. The dimensions of the PCB are approximately 4 by 9 inches.

Fabrication

Fabrication of the PCB design was done by JLCPCB located in Hong Kong. The PCB was designed using 2-layers and lead-free coating. The fabrication was done relatively quickly, however, due to the COVID-19 outbreak, delivery of the PCB was delayed.

Challenges

Some challenges encountered when designing the PCB was the delay in pinout information needed to begin designing the PCB. It is advised to order parts early and determine what ports/pins are needed as soon as possible to begin designing and ordering the PCB. Another challenge was some issues with the files needed to be manufactured. Since the design had to be designed using DipTrace instead of EAGLE, exporting the necessary files needed to order for fabrication is slightly different than EAGLE.

Project Nimble PCB RevA.jpg

PCB Proj Nimble physical.JPG



CAN Communication

<Talk about your message IDs or communication strategy, such as periodic transmission, MIA management etc.>

Hardware Design

Where Each Individual Controller Node should have it's responding Block diagram with it's connected Devices, Below is just brief illustration of connection for CAN bus.

Overall diagram of CAN

DBC File

Shown below is the DBC implementation for this project.

VERSION ""

NS_ :
	BA_
	BA_DEF_
	BA_DEF_DEF_
	BA_DEF_DEF_REL_
	BA_DEF_REL_
	BA_DEF_SGTYPE_
	BA_REL_
	BA_SGTYPE_
	BO_TX_BU_
	BU_BO_REL_
	BU_EV_REL_
	BU_SG_REL_
	CAT_
	CAT_DEF_
	CM_
	ENVVAR_DATA_
	EV_DATA_
	FILTER
	NS_DESC_
	SGTYPE_
	SGTYPE_VAL_
	SG_MUL_VAL_
	SIGTYPE_VALTYPE_
	SIG_GROUP_
	SIG_TYPE_REF_
	SIG_VALTYPE_
	VAL_
	VAL_TABLE_

BS_:

BU_: DBG DRIVER IO MOTOR SENSOR BRIDGE GPS COMPASS CMP

BO_ 150 MOTOR_CMD: 3 DRIVER
 SG_ MOTOR_CMD_STEERING : 0|8@1+ (1,-2) [-2|2] "" MOTOR 
 SG_ MOTOR_CMD_SPEED : 8|8@1+ (1,-25) [-25|25] "" MOTOR

BO_ 151 MOTOR_DATA: 4 MOTOR
 SG_ MOTOR_DATA_RPM: 0|32@1+ (1,0) [0|0] "" DRIVER

BO_ 200 SENSOR_DATA: 8 BRIDGE
 SG_ SENSOR_SONARS_left : 0|16@1+ (1,0) [0|0] "cms" DRIVER
 SG_ SENSOR_SONARS_mid : 16|16@1+ (1,0) [0|0] "cms" DRIVER
 SG_ SENSOR_SONARS_right : 32|16@1+ (1,0) [0|0] "cms" DRIVER
 SG_ SENSOR_IR_rear : 48|16@1+ (1,0) [0|0] "cms" DRIVER

BO_ 300 GPS_DESTINATION_INFO: 8 BRIDGE
SG_ GPS_DESTINATION_LAT : 0|32@1+ (0.000001,-90.000000) [-90|90] "degrees" DRIVER,GPS,MOTOR
SG_ GPS_DESTINATION_LONG : 32|32@1+ (0.000001,-180.000000) [-180|180] "degrees" DRIVER,GPS,MOTOR

BO_ 301 GPS_CURRENT_INFO: 8 GPS
SG_ GPS_CURRENT_LAT : 0|32@1+ (0.000001,-90.000000) [-90|90] "degrees" DRIVER,BRIDGE,MOTOR
SG_ GPS_CURRENT_LONG : 32|32@1+ (0.000001,-180.000000) [-180|180] "degrees" DRIVER,BRIDGE,MOTOR

BO_ 302 COMPASS: 6 GPS 
 SG_ CMP_DEST_BEARING : 0|16@1+ (0.1,0) [0|359.9] "degrees" DRIVER,BRIDGE,MOTOR
 SG_ CMP_CURRENT_HEADING : 16|16@1+ (0.1,0) [0|359.9] "degrees" DRIVER,BRIDGE,MOTOR
 SG_ CMP_DISTANCE : 32|16@1+ (0.01,0) [0|0] "meters" DRIVER,BRIDGE 
   
BO_ 105 SENSOR_DEBUG: 1 BRIDGE
 SG_ IO_DEBUG_CAN_init : 0|1@1+ (1,0) [0|0] "" DBG
 SG_ IO_DEBUG_sensor_init : 1|1@1+ (1,0) [0|0] "" DBG
 SG_ IO_DEBUG_sensor_data : 2|1@1+ (1,0) [0|0] "" DBG
 SG_ IO_DEBUG_bus_off : 3|1@1+ (1,0) [0|0] "" DBG
 
BO_ 106 MOTOR_DEBUG: 6 MOTOR
 SG_ IO_DEBUG_CAN_init : 0|1@1+ (1,0) [0|0] "" DBG,DRIVER
 SG_ IO_DEBUG_bus_off : 1|1@1+ (1,0) [0|0] "" DBG,DRIVER
 SG_ IO_DEBUG_Steering : 2|8@1+ (1,-2) [-2|2] "" DBG,DRIVER
 SG_ IO_DEBUG_RPM : 10|32@1+ (1,0) [0|0] "" DBG,DRIVER
 
BO_ 107 DRIVER_DEBUG: 1 DRIVER
 SG_ IO_DEBUG_CAN_init : 0|1@1+ (1,0) [0|0] "" DBG
 SG_ IO_DEBUG_bus_off : 1|1@1+ (1,0) [0|0] "" DBG
 SG_ IO_DEBUG_DRIVER : 3|1@1+ (1,0) [0|0] "" DBG

BO_ 108 GPS_DEBUG: 1 GPS
 SG_ IO_DEBUG_CAN_init : 0|1@1+ (1,0) [0|0] "" DBG
 SG_ IO_DEBUG_bus_off : 2|1@1+ (1,0) [0|0] "" DBG
 SG_ IO_DEBUG_GPS : 3|1@1+ (1,0) [0|0] "" DBG
 SG_ IO_DEBUG_Compass : 5|1@1+ (1,0) [0|0] "" DBG

BO_ 109 BRIDGE_DEBUG: 1 BRIDGE
 SG_ IO_DEBUG_CAN_init : 0|1@1+ (1,0) [0|0] "" DBG
 SG_ IO_DEBUG_bus_off : 2|1@1+ (1,0) [0|0] "" DBG
 SG_ IO_DEBUG_Bridge : 4|1@1+ (1,0) [0|0] "" DBG 

CM_ BU_ DRIVER "The driver controller driving the car";
CM_ BU_ MOTOR "The motor controller of the car";
CM_ BU_ BRIDGE "The bridge controller of the car";
CM_ BU_ GPS    "The GPS controller of the car";
CM_ BO_ 100 "Sync message used to synchronize the controllers";
CM_ SG_ 100 DRIVER_HEARTBEAT_cmd "Heartbeat command from the driver";

BA_DEF_ "BusType" STRING ;
BA_DEF_ BO_ "GenMsgCycleTime" INT 0 0;
BA_DEF_ SG_ "FieldType" STRING ;

BA_DEF_DEF_ "BusType" "CAN";
BA_DEF_DEF_ "FieldType" "";
BA_DEF_DEF_ "GenMsgCycleTime" 0;

BA_ "GenMsgCycleTime" BO_ 100 1000;
BA_ "FieldType" SG_ 100 DRIVER_HEARTBEAT_cmd "DRIVER_HEARTBEAT_cmd";

VAL_ 100 DRIVER_HEARTBEAT_cmd 2 "DRIVER_HEARTBEAT_cmd_REBOOT" 1 "DRIVER_HEARTBEAT_cmd_SYNC" 0 "DRIVER_HEARTBEAT_cmd_NOOP" ;




Sensor ECU

<Picture>

Sensor node Gitlab

The sensor and bridge controller consists of sensor module that is responsible for object detection. Nimble uses ultrasonic sensors to achieve this task. As the name suggests, an ultrasonic sensor emits ultrasonic signal or beam from its head, and on encountering an object, returns back. This technique is better known as echolocation as we used sound signals to do so. The distance of the object is calculated based on the output and this ensures object detection. The distance measured is continuously passed on to driver node through can transceiver. The driver controller further processes the distance values of all the sensors on nimble and acts in accordance with the values to achieve obstacle avoidance.

Hardware Design

We have embedded 4 sensors on Nimble. We have arranged 3 LV-MaxSonar-EZ series Maxbotix ultrasonic sensors in the front section of the car; one at right, one at left and one in the center. The fourth Ultrasonic sensor is placed at the rear end of the car. These sensors provide very short to long-range detection. It provides sonar range information from 6-inches out to 254-inches with 1-inch resolution.

   Nimble- sensor and board connection diagram rev.jpg            Pin description of ultra.jpg


A maxbotix sensor gives out 3 types of output- analog, RS232, and Pulse width. We have used analog output and hence, utilized on-board analog to digital converters- ADC2 (P0.25), ADC3 (P0.26), ADC4 (P1.30), and ADC5 (P1.31). To trigger all the four ultrasonic sensors, we used P0.6, P0.7, P0.8 and P0.9 of SJTWO board. The analog output is converted to digital and transmitted to the driver controller. The converted adc distance data is passed to driver by Can transceiver. P0.0 is used as CAN RX and P0.1 as CAN TX on the Sensor module.

Hardware Interface

Sensors are interfaced with combination of GPIO, ADC Pins on SJTWo board. Below is the descriptive pin layout:

Sensors pin layout
Sr. No. SJTwo board Pin Maxbotix sensor Pin Function
1 ADC2-P0.25 AN(Left) ADC input from left sensor
2 ADC3-P0.26 AN(Rear) ADC input from rear sensor
3 ADC4-P1.30 AN(Right) ADC input from right sensor
4 ADC5-P1.31 AN(Middle) ADC input from middle sensor
5 P0.6 RX(Right) Trigger for right sensor
6 P0.7 RX(Left) Trigger for left sensor
7 P0.8 RX(Middle) Trigger for middle sensor
8 P0.9 RX(Rear) Trigger for rear sensor

Software Design

The sensor implementation is mostly done in 100HZ function of periodic callbacks. The basic operation objective is to trigger all the sensors whenever (count%5==0) one after another and get the converted minimum distance value from ADC readings every time (count%5 ==4). As we have used Analog output, we used on board ADC and we had to make few changes in the ADC driver. The SJTWO board has 4 ADC but the pin out diagram showed only 3 and misnamed one ADC with DAC (P0.26). So we added P0.26 that is ADC3 channel into the code and modified the ADC driver accordingly. The ADC readings are basically in form of raw voltage and hence are converted to distances in centimetres. To get the most accurate distance value of each sensor, we used buffer that gives out the minimum distance reading. This distance is sent over CAN to driver controller which further processes these distances and coordinates the movement of car accordingly. The flowchart below shows the implementation of our sensor controller.


                   Flowchart.jpg


A. Initialization:

1. Initialization of sensors: As we are using on board ADC to get voltage, we first initialize all the ADCs (ADC2, ADC 3, ADC 4, ADC 5). We then configured IOCON registers to set up all the ADC’s.

2. Initialized Buffer and can.

B. Triggering the sensors:

1. Configured the SJTWO pin connected to sensor’s RX as GPIO output. This pin will be served as trigger pin to the sensors.

2. The sensors are triggered in 100Hz functions. To do so, trigger pin is set for 30 microseconds and the reset.

3. Triggered all the sensors every time (count%5==0) one after other, starting with left, right, middle and lastly rear.

C. Read sensor values:

We are using ADC values to obtain the distance. All the values are in form of analog voltage and represents number of steps in terms of voltage level. To get real voltage value from raw, it is multiplied by adc voltage and divided by voltage scaling defined by voltage level powering the sensors (here 3.3 V) and manufacturing scaling (Vcc/512). The distance values obtained are stored in buffer. All the sensors have individual buffer that collects the distance values and get the minimum of all the values.

D. CAN transmission:

The lowest distance in cm of all the sensors are sent to driver controller over CAN bus. We have used CAN1 to achieve this task. The driver then coordinates the movement according to the distance value.

Technical Challenges

< List of problems and their detailed resolutions>



Motor ECU

Our Motor Controller node is responsible to control the DC and Servo motor from the RC car, and additional RPM sensor measurement to get the RPM value from each rotation so we can have control to the speed or our RC car. The motor controller logic the steering and speed will be calculated within the Driver Node Controller through the CAN bus messages. Then, the Motor Controller node will output the feedback of RPM value for the Driver node to display the RPM value through CAN bus to the Driver module. The Motor controller node will also use this RPM feedback from the sensor to maintaining the speed making sure that the car is under certain threshold of RPM value, so it won't become too fast or too slow. The CAN message function will be constantly called at 10Hz of the periodic callbacks, while the speed check for the RPM value will be call every 500 ms.

Motor node Gitlab

Hardware Design

The hardware interface details of MOTOR Module with SJOne board are given above:

Overall outlook in RC car
Overall circuit


Label Function Pin Connection
1 Can RX Pin 0.0
2 Can TX Pin 0.1
3 RPM Signal Pin 2.6
4 Servo Motor Signal Pin 2.1
5 DC motor Signal PIn 2.0
20 GND Pin GND


Hardware Interface

SERVO Motor

The direction of the RC car is dependent on the servo motor, based on various PWM signals of 10% to 20% it will steers the front wheels from right to left direction. The servo motor has 3 wires, where one is the PWM input signals, other two wires responsible to the VCC of 6V and Ground. We powered our Servo motor using the ESC output voltage from the Lipo battery of the RC car, and the PWM signals will be generated from motor controller of P2.1 of SJtwo Board.

Servo motor
Label Function PWM_value
1 Left PWM -> 15.1 - 20
2 Middle PWM -> 15
3 Right PWM -> 10 - 14.9
Label Function Pin Connection
1 VCC from Lipo 7.2V to Servo VCC
2 Servo Signal to SJtwo P2.1
3 GND Pin GND

DC Motor

The DC motor is already connected with the ESC as default built-in from the RC car, the purpose of ESC (Electronic Speed Control) is to control the DC motor Using PWM signals from the controller. It also regulated (converted) the 7.4V Lipo battery power sources into stable 6V energy output for the DC motor and servo. The DC motor is similar to the Servo where it takes in 10% to 20% duty cycle of PWM signals to control the RC car Forward, Stop, and Reverse mode. One thing that's interesting is that there is certain sequence for the DC motor to go from Forward state into the Reverse state, based from the design of the ESC it is to protect the DC motor from breaking.

The sequence of the DC motor to go to Reverse is that it have to received the PWM of Reverse duty cycle for two times before it actually starting to go in reverse direction.

DC motor
ESC


Label Function Pin Connection
1 VCC from Lipo 7.2V to ESC VCC
2 DC Signal from ESC P2.0
3 GND Pin GND
Label Function PWM_value
1 Left PWM -> 15.1 - 20
2 Straight PWM -> 15
3 Right PWM -> 10 - 14.9

RPM Sensor

RPM sensor is the device that calculated the one single rotation per certain duration of time frame. It can be a device that used magnet to calculated one rotation or IR Optocoupler with its corresponding disk, as long as the device can successfully achieve the job of counting one rotation cycle. Our RPM sensor in mounted on the car shaft instead of the built-in RPM sensor from Traxxas, when ever the IR Optocoupler sending the signals to the P2.6 as the interrupts it will increment the rotation_count for the computation on the RPM value. The IR Optocoupler have 4 PIN, where we only used its VCC, GND, and D0 for our RC car, the VCC need power of 3.3V to 5V to properly power-up the device, and the GND should have common GND that connected all the devices, while D0 pin will goes to P2.6 in our Motor Controller.

RPM value
Label Function Pin Connection
1 VCC from 5V Portable Power Bank VCC
2 RPM Signal to P2.6 D0
3 GND Pin GND


Software Design

The dc motor and servo motor operation is fundamentally based on PWM (Pulse Width Modulation). We set the PWM frequency to 100Hz for both dc and servo motor.

Pseudo code for initializing PWM to 100Hz.

 gpio__construct_with_function(2, 0, 1); 
 gpio__construct_with_function(2, 1, 1); 
 // gpio input for interrupt
 gpio__construct_as_input(2, 6);
 // gpio initialize the interrput
 gpio2__attach_interrupt(6, GPIO_INTR__RISING_EDGE, pwm_get_speed);
 lpc_peripheral__enable_interrupt(LPC_PERIPHERAL__GPIO, pwm_get_speed, NULL);
 pwm1__init_single_edge(frequency_in_hertz); // usually use 100 hz
DC Motor Flow Chart - State Machine
Servo Motor Flow Chart
RPM Flow Chart


Servo motor Pseudo Code

The servo motor is connected to the Pin 2.1 on SJTwo Board. The servo received the command of -2 to 2 from the can1 of driver node every 10 Hz, where the -2 represents full left and 0 as neutral and 2 as full right turn. Then the data from CAN bus of driver node will be process under if statement to select the respective rotation of the servo motor according to the data received from the driver logic. Under is some Pseudo logic of the function, once the rotation is finish selected it will use motor_control_status__process_data(); to choose the respective PWM of the Servo, where left would be 20 and right would 10 and 15 as neutral state of the servo motor.

 if (motor_cmd_data->MOTOR_CMD_STEERING == steer_left) {
   motor_control_status__process_data(MOTOR_STATUS_LEFT);
 } else if (motor_cmd_data->MOTOR_CMD_STEERING == steer_right) {
   motor_control_status__process_data(MOTOR_STATUS_RIGHT);
 } else if (motor_cmd_data->MOTOR_CMD_STEERING == steer_slight_left) {
   motor_control_status__process_data(MOTOR_STATUS_SLIGHTLY_LEFT);
 } else if (motor_cmd_data->MOTOR_CMD_STEERING == steer_slight_right) {
   motor_control_status__process_data(MOTOR_STATUS_SLIGHTLY_RIGHT);
 } else if (motor_cmd_data->MOTOR_CMD_STEERING == steer_straight) {
   motor_control_status__process_data(MOTOR_STATUS_STRAIGHT);
 }

DC motor Pseudo Code

The DC motor is connected to the Pin 2.0 on SJTwo Board. The DC received the command of PWM every 10 Hz, where the 20 represents full forward and 15 as neutral and 10 as full reverse. Because the value of DC motor when it is 20 or 10 would be too fast for the sensor to even react and transfer the signal to the motor node, we reduce the forward and reverse PWM as 15.5 for forward and 14.5 for reverse. The DC motor will be modify under the switch case state machine for FORWARD, REVERSE, STOP state of the DC motor. And the RPM sensor will be getting the speed of the RC car to increase or reduce the speed of the RC car in term of PWM. Below is partial code of the FORWARD state. The pwm_request_by_app will receive the speed request of from driver node in CAN1 bus, which will select and make the state change accordingly, and pwm_maintain_speed_forward(); will just be using the PWM sensor in the next section to monitor the rotation of the RC car so it doesn't be come too fast or too slow.

  if (0 >= pwm_request_by_app) {
     pwm_DC_motor(motor_speed_stop);
     pwm_servo_motor(servo_center);
     motor_value_type = MOTOR_STATUS_STOP;
     break;
   }
   pwm_maintain_speed_forward();

RPM sensor Calculation Pseudo Code

The RPM sensor is connected to the Pin 2.6 on SJTwo Board. It will received the signals from the every time it finish the single rotation. It will use interrupt to register these pulses in a 500ms time frame and then calculate the speed in m/s based on the formula:

 rotation_per_min = rotation_value * ((60s * 1000hz "1 second")/duration_time) //where the duration_time is 500ms.

Because there is some difficulty in installing the magnet RPM sensor into the RC car, we end up using the LM393 Speed Detection Sensor Module with the Type IR Optocoupler and it's respective disks for the IR Optocoupler. So within one single rotation it will received 20 rotation_count, which them we will have to divided the rotation_count we received from the interrupt by 20 to get the actual one rotation from the wheel. The equation will be the following below.

   rotation_value = rotation_count / 20;

And rotation_count will be received using code below.

 rotation_count = rotation_count + 1;
 clear_pin_interrupt2(6);




Technical Challenges

< Updating later>

  • Issue 1: Probably one of the most difficult challenges to deal with in this project was the inaccuracy of the GPS module. The default readings of this GPS module would be read were not even remotely close to its actual location.
    • Solution: Although we did not fully fix this issue, the method that we dealt with the poor accuracy was to implement manual calibration with respect to the actual location of the module using google maps, and either adding or subtracting an offset to the GPS coordinates received from the GPS module.
  • Issue 2: Calibration of the compass was another issue. Each time the compass module would boot up, the readings of the heading angle would be off by a considerable amount.
    • Solution: The solution to solve this was to send calibration commands to the compass module through button press. Helpful commands to send to the compass was erasing the calibration profile and setting default calibration settings.
  • Issue 3: The checkpoints set using google maps for our area used for testing were shifted when doing physical testing with the RC car. This was due to the poor accuracy of the GPS despite our efforts in performing some manual calibration of the GPS.
    • Solution: The solution, although not perfect, was to set an offset to the original checkpoints such that the newly shifted coordinates would reflect the checkpoints originally set using google maps.




Geographical Controller

Geo Module Gitlab link

The geographical controller is responsible for interfacing with a GPS and Compass module in order to receive the current heading(in degrees) and the current destination in the form of GPS coordinates (in degrees, hours, minutes, seconds). It is also responsible for receiving the needed destination coordinates sent by the BRIDGE controller which are needed along with the current GPS location coordinates to calculate the destination heading angle and distance to destination and checkpoints. The current compass heading angle is also sent to the DRIVER controller such that it can be integrated into the driver logic to determine the heading angle to steer and drive towards the destination.

Hardware Design

In essence, the Geo-controller is interfaced with a GPS and Compass through UART2 and UART3, respectively. Additionally, the Geo-controller is interfaced with a CAN transceiver in order to receive and send messages from and to other nodes.

Geo Controller Hardware Design

Hardware Interface

GPS

The GPS is responsible for sending GPS NMEA sentences to the Geographical controller to parse and tokenize in order to get the current latitude and longitude in the units, degrees:hours:minutes:seconds. The sentence desired to extract the coordinates is the GPGGA sentence which contains fixed GPS coordinates. The GPS module that we used for this project was the "Ultimate GPS breakout board" from Adafruit. The module was interfaced with the UART2 port of the SJTwo LPC4078 Controller with a baud rate of 9600 and with 1 stop bit.

Ultimate GPS Breakout board from Adafruit
GPS pin layout
No. SJTwo Controller Pin Ultimate GPS Breakout Pin Function
1 UART2-P2.8(TX) RX UART TX from SJTwo to RX port of GPS module
2 UART2-P2.9(RX) TX UART RX from SJTwo to TX port of GPS module
3 Power Bank VCC-5.0V Power(Vin) Powering gps module
4 Ground Port GND ground port of gps module
Compass

The compass is required to get the current heading of the RC car such that it can send the heading information from the geographical controller to the driver controller to perform destination navigation as part of the driver logic. The compass module purchased for this project was the CMPS14 compass module. This module was interfaced to the (Geographical) SJTwo controller using UART3, a baud rate of 9600, and 2-stop bits. The compass can be operated in two modes, I2C and serial(UART) mode. The compass utilized for the project was set in serial mode using UART2. Its register contents and various commands include receiving the bearing angle in 16 or 8-bit and altering the calibration settings and profiles. Additionally, the cmps14 is tilt-compensated and includes an accelerometer, gyro-meter, and magnetometer.

CMPS14 Compass Module
Compass pin layout
No. SJTwo Controller Pin CMPS14 Pin layout Function
1 UART3-P4.28(TX) RX UART TX from SJTwo to RX port of Compass module
2 UART3-P4.29(RX) TX UART RX from SJTwo to TX port of Compass module
3 Vcc(3.3v) Power(Vin) Powering compass module
4 Ground Port GND ground port of compass module
5 Ground Port Mode Pin Compass mode pin Ungrounded(I2C) Grounded(UART)
CMPS14 Registers and Commands for Serial Mode
Compass Calibration flow-chart

Software Design and Implementation

High-level software flow of the geographical controller and periodic callbacks utilized.

Geo controller software flow chart
Periodic Callbacks 1Hz software flow chart
Periodic Callbacks 10Hz software flow chart

GPS NMEA sentence parsing and tokenization

GPS run once is called in the 10Hz periodic callback and is essentially done through obtaining a stream of (GPS NMEA sentence) bytes from the GPS module through UART, storing the stream into a line buffer FIFO. The stream of bytes are then popped to a handle line where the stream of bytes or the GPS strings are then handled and processed by checking for the $GPGGA sentence, in particular, using strstr(). If the string "$GPGGA" is found, then tokenization begins using sscanf() for the relevant information required for extraction: latitude, latitude direction, longitude, longitude direction, and the valid fix value. Before the essential information is extracted, a check must be made using the extracted valid GPS fix value. If the valid GPS fix is greater than 0 (1 or 2 are the only possibilities), then it indicates a valid GPS fix versus, otherwise, if the value is 0, then it is an invalid fix, therefore it should not extract the coordinates. If the latitude direction is South("S" or "s"), then the coordinates extracted will be multiplied by -1. Similarly, if the longitude direction is West("W" or "w"), then the extracted longitude is multiplied by -1. Manual calibration is also implemented by(in our case) adding to the latitude and longitude coordinates. This was done because the readings given to us by the GPS were very poor.

GPS Parsing software flow-chart

Calculating destination bearing angle

Calculating the destination bearing angle between the current and destination longitude and latitude coordinates was done using the formula as follows...

 Formula: θ = atan2( sin Δλ ⋅ cos φ2 , cos φ1 ⋅ sin φ2 − sin φ1 ⋅ cos φ2 ⋅ cos Δλ )
   
 where...
 θ  = destination bearing angle
 φ1 = Latitude of origin coordinate
 φ2 = Latitude of destination coordinate
 λ1 = Longitude of origin coordinate
 λ2 = Longitude of destination coordinate
 Δλ = λ2 - λ1

Calculating destination distance

The destination distance between current and destination longitude and latitude coordinates was calculated using the haversine formula.

 a = sin²(Δφ/2) + cos φ1 ⋅ cos φ2 ⋅ sin²(Δλ/2)
 c = 2 ⋅ atan2( √a, √(1−a) )
 d = R ⋅ c
 
 where...
 R = earth's radius = 6,371,000 meters
 d = distance between current and destination gps coordinates
 c = angular distance in radians
 a = is the square of half the chord length between the points.

Testing Area and GPS Navigation Checkpoint algorithm

The test are we chose was in a small intersection in a suburban neighborhood. The checkpoints set were set in a manner that would demonstrate that the RC car can navigate through the intersection without cutting through corners through sidewalks as a real would do so. The Longitude and Latitude coordinates were taken from google maps and used to insert into a static const struct array. The algorithm must iterate through the array of checkpoints and determine which point would be navigated towards next based on how close the point is to the car and at the same time how close the point is to the destination.

Checkpoints set on google maps
Checkpoint software design flow-chart

Technical Challenges

  • Issue 1: Probably one of the most difficult challenges to deal with in this project was the inaccuracy of the GPS module. The default readings of this GPS module would be read were not even remotely close to its actual location.
    • Solution: Although we did not fully fix this issue, the method that we dealt with the poor accuracy was to implement manual calibration with respect to the actual location of the module using google maps, and either adding or subtracting an offset to the GPS coordinates received from the GPS module.
  • Issue 2: Calibration of the compass was another issue. Each time the compass module would boot up, the readings of the heading angle would be off by a considerable amount.
    • Solution: The solution to solve this was to send calibration commands to the compass module through button press. Helpful commands to send to the compass was erasing the calibration profile and setting default calibration settings.
  • Issue 3: The checkpoints set using google maps for our area used for testing were shifted when doing physical testing with the RC car. This was due to the poor accuracy of the GPS despite our efforts in performing some manual calibration of the GPS.
    • Solution: The solution, although not perfect, was to set an offset to the original checkpoints such that the newly shifted coordinates would reflect the checkpoints originally set using google maps.




Communication Bridge Controller

<Picture and link to Gitlab>

Bridge controller GitLab link

Hardware Design

The hardware for communication between the micro controller and the app was using the HC-05 Bluetooth module. The main communication between the controller and the Bluetooth was UART at a 115200 Baud rate.

Software Design

<List the code modules that are being called periodically.> The software for this part was a Bluetooth module for the SJ2 board. This would take incoming data from the sensors and send the data using a module called bluetooth.h which would then be parsed by python in the main app to send to the front end.

Technical Challenges

< List of problems and their detailed resolutions>

  • Issue 1: Bluetooth module - the main problem with this was trying to get the parts to print on Hercules after sending data from the App.
    • Solution: This issue was resolved once the stop bits were figured out.
  • Issue 2: Data formation - a problem with this was getting the correct way to send data to the Python back end and then parsing the information.
    • Solution: This was resolved by making the data sent in a certain way.


Driver Module & LCD

Driver Module Gitlab link

The driver controller is responsible for performing driver logic which will execute both obstacle avoidance and destination navigation.

Hardware Design

Driver Controller Hardware Design

Hardware Interfacing

20x4 LCD Display
Compass pin layout
No. SJTwo Controller Pin LCD I2C backpack Pin Function
1 UART3-P4.28(TX) RX UART TX from SJTwo to RX port of Compass module
2 UART3-P4.29(RX) TX UART RX from SJTwo to TX port of Compass module
3 Vcc(3.3v) Power(Vin) Powering compass module
4 Ground Port GND ground port of compass module
5 Ground Port Mode Pin Compass mode pin Ungrounded(I2C) Grounded(UART)

Software Design

Driver controller software flowchart
Driver Periodic callback 1Hz software flow chart
Driver Periodic 10Hz software flow chart
Driver Periodic 20Hz software flow chart

Technical Challenges

  • Issue 1: The first issue with the driver controller was testing obstacle avoidance in a physical test with the RC car. This issue was mostly trial and error when trying to set well-balanced sensor thresholds.
    • Solution: Trial-and-error in doing physical tests to see how the RC car reacts and to determine what sensor value threshold would be adequate enough to detect objects far enough such that the RC car has enough time to react.
  • Issue 2: Another issue that we faced was updating the LCD display. Since the commands that are required to be sent to the LCD require some delays, updating the LCD in a periodic call in the 10Hz or above would end up resetting the micro-controller.
    • Solution: Putting the LCD display update function was put into the 1Hz periodic callback.


Mobile Application

App.PNG

Mobile App Gitlab link

Software Design

The software's main front end code was written in Javascript while the backend was written in Python flask to send and receive data from the microcontroller to the app. The methods of sending GPS coordinates from the app to the microcontroller was using a location's address or a point and click map from google. To receive the data from the microcontroller, the data had to be sent from the Bluetooth module in a specific way such that python could parse through the data and then separate it into sensor and sensor value. The sent data would be picked up every five seconds so that this would allow for the user to send data without having sockets closing from the code before the data could send.

App diagram.PNG

Technical Challenges

The main technical challenge was learning Javascript without having any prior experience in coding Javascript, but to do this lots of research was done on how to make classes, send data to the backend, and how to make the webpage dynamic in updating information. Another challenge was making the Bluetooth module work with the microcontroller for this class. The difficulties in this were that the Bluetooth module was made for an Arduino so the settings had to be modified so that it could work with other microcontrollers by modifying the Baud rate and stop bits. The last technical challenge was working with a python backend. The reason for this is that there is a method that was needed to get information from the front end that was not familiar to the normal python, instead of GET and POST methods had to be researched to get the data and then printed on the webpage instead of using a simple print function.

Javascript and React-framework: The challenge in this was learning a new language, but to resolve this many youtube videos were watched and forums were read to learn how to program in a new language.
Bluetooth module development: This was difficult because the stop bits had to be played around with until the right one was selected, but after changing the values around the proper setup was made after a while
Flask and python backend: The problems with this were programming in an unconventional python way, instead, it dealt with POST and GET methods to gather front end data and if there were errors then the simple print functions couldn't be used to find the values of variables but they had to be printed onto a second webpage. To fix this, many tries were taken to try and get the data from the front end as well as finding a way to find the data values easier.






Conclusion

<Organized summary of the project>

Nimble was a great opportunity to learn test-driven design strategies, which helped lower the amount of time troubleshooting issues. It also taught us much about using Git for version control. The project also gave us experience working with embedded systems technologies such as CAN bus communications, DBC files, GPIO, and signal debugging with BusMaster.

Project Video

[Team Nimble RC Car video link]

Project Source Code

Gitlab Project Link - [6]

Advice for Future Students

  • Advice 1: Always make sure the teammate you choose is being responsible of their tasks, since teammate is the most important part of this group project. If any teammate is not being responsible make sure you pursue them and keep tracking on their progress, otherwise, you will be ending up finishing and fixing their lack of progress. Also, make sure you get your teammates' contact information beside slack, something that can access them easily.
  • Advice 2: Set an earlier deadline and make sure your teammate will finish before the deadline, there should not be any tolerance because this project will be difficult when there is a lack of contribution from all team members. If there are not strong leaders within your team, the result of your project will not be looking too great. Also, assigned an important task like GPS and Mobile application to someone with the most knowledgeable and most reliable, since those two are by far the most difficult part of the RC car. A rough draft of the mobile application should be highly considered early on, especially if nobody in your team has experience in mobile app development. It is HIGHLY recommended to refer to previous semesters TEAM to get a GOOD LOOK of what expectation the mobile application Preet is looking for.
  • Advice 3: Make sure the GPS modules you purchase is somewhat over $90 where it is most reliable, DO NOT, I repeat DO NOT purchased the GPS our team purchase, where it is shown significant failure. Make sure you guys spend more money on the GPS module
  • Advice 4: Plan a backup plan in case something goes wrong, always make sure you gave your self enough time in the end to polish your final work of the Project. This including enclosure, or accident like CORONA virus this semester, make sure you can adapt to the situation quickly. WHEN THINGS REALLY GOES WRONG WHETHER TEAMMATE OR THE LIFE ALWAYS TALK WITH PROFESSOR AND ISAs RIGHT AWAY
  • Advice 5: Overall this is an interesting class project, where you do learn a lot. Please do take advantage of this project by asking Preet a lot of questions. Again, TEAMMATE you choose will be important DO NOT wait until the second lecture to form your team. Make sure you form your team during the first two weeks of the lecture!

Acknowledgement

References

  • The website used to calculate destination distance(haversine formula) and the destination heading angle:link