Difference between revisions of "S19: Tech Savy"

From Embedded Systems Learning Academy
Jump to: navigation, search
(Master Module)
(Project Source Code)
 
(40 intermediate revisions by the same user not shown)
Line 88: Line 88:
 
* <font color="MAROON"><B>Communication Bridge Controller</B></font>
 
* <font color="MAROON"><B>Communication Bridge Controller</B></font>
 
**'''''[https://www.linkedin.com/in/akshata-kulkarni-a9145b62 Akshata Kulkarni]'''''
 
**'''''[https://www.linkedin.com/in/akshata-kulkarni-a9145b62 Akshata Kulkarni]'''''
**'''''[https://www.linkedin.com/in/vidushi-jain-048b992a Vidushi Jain]'''''  
+
**'''''[https://www.linkedin.com/in/vidushi-jain-048b992a Vidushi Jain]'''''
 +
**'''''[https://www.linkedin.com/in/saumil-shah-a49849166 Saumil Shah]'''''
  
 
* <font color="brown"><B>Android Application</B></font>
 
* <font color="brown"><B>Android Application</B></font>
 +
**'''''[https://www.linkedin.com/in/saumil-shah-a49849166 Saumil Shah]'''''
 
**'''''[https://www.linkedin.com/in/akshata-kulkarni-a9145b62 Akshata Kulkarni]'''''
 
**'''''[https://www.linkedin.com/in/akshata-kulkarni-a9145b62 Akshata Kulkarni]'''''
**'''''[https://www.linkedin.com/in/saumil-shah-a49849166 Saumil Shah]'''''
 
  
 
* <font color="fire"><B>LCD Interfacing & UI Designing</B></font>
 
* <font color="fire"><B>LCD Interfacing & UI Designing</B></font>
Line 497: Line 498:
  
 
=='''CAN Communication'''==
 
=='''CAN Communication'''==
<Talk about your message IDs or communication strategy, such as periodic transmission, MIA management, etc.>
+
*As the DBC file shows, master is given the highest priority after bridge start/stop command message.
 +
*All messages from every controller are send to Bridge and Motor as well along with Master, to display it on Android app and LCD Controller for debugging and testing.
 +
*Every controller is also sending Initialization Debug messages over CAN, to verify it on BusMaster.
 +
*1Hz task is used to check CAN_bus_off() condition, along with send heartbeat and debug message messages over can.
 +
*As master is the major receiver of all the signals, it perform MIA handling of all necessary signals along with heartbeat as well.
 +
*We have also used plenty of LEDs for confirming we get correct heartbeat and data.
 +
*The code for master MIA initialization is as shown below,
 +
 
 +
  const uint32_t                            BRIDGE_NODE__MIA_MS = 3000;
 +
  const BRIDGE_NODE_t                        BRIDGE_NODE__MIA_MSG = { 0, {0} };
 +
  const uint32_t                            SENSOR_NODE__MIA_MS = 3000;
 +
  const SENSOR_NODE_t                        SENSOR_NODE__MIA_MSG = { 0 };
 +
  const uint32_t                            GPS_LOCATION__MIA_MS = 3000;
 +
  const GPS_LOCATION_t                      GPS_LOCATION__MIA_MSG = { 37.3686485, -121.9153289, {0} };
 +
  const uint32_t                            COMPASS__MIA_MS = 3000;
 +
  const COMPASS_t                            COMPASS__MIA_MSG = { 37.3686485, -121.9153289, 0.0, {0} };
 +
  const uint32_t                            SENSOR_HEARTBEAT__MIA_MS = 3000;
 +
  const SENSOR_HEARTBEAT_t                  SENSOR_HEARTBEAT__MIA_MSG = {0, {0}};
 +
  const uint32_t                            MOTOR_HEARTBEAT__MIA_MS = 3000;
 +
  const MOTOR_HEARTBEAT_t                    MOTOR_HEARTBEAT__MIA_MSG = {0, {0}};
 +
  const uint32_t                            GPS_HEARTBEAT__MIA_MS = 3000;
 +
  const GPS_HEARTBEAT_t                      GPS_HEARTBEAT__MIA_MSG = {0, {0}};
 +
  const uint32_t                            BRIDGE_HEARTBEAT__MIA_MS = 3000;
 +
  const BRIDGE_HEARTBEAT_t                  BRIDGE_HEARTBEAT__MIA_MSG = {0, {0}};
  
 
==Hardware Design==
 
==Hardware Design==
Line 632: Line 656:
 
<BR/>
 
<BR/>
  
== '''LED Functionality in PCB''' ==
+
=='''DBC File'''==
 +
A Link to the DBC file that defines the CAN communication of the system is as follows:
 +
[https://gitlab.com/tech-savycmpe243/cmpe243_techsavy_rc_car/blob/master/PROJ_DBC_File/243_techSavvy.dbc DBC link on GitLab]
 +
<br>
 +
 
 +
DBC is a format that enables fewer hassles while developing code to either interpret data received or send data over the CAN bus. This project used DBC effectively.
  
{| class="wikitable"  
+
Shown below is the DBC implementation for this project.
|-
+
<pre>
! scope="col" style="text-align: left;" style="background:#7acee2;" | <span style="color:#FFFFFF">
+
VERSION ""
LED DESIGNATION</span>
+
 
! scope="col" style="text-align: left;" style="background:#7acee2;" | <span style="color:#FFFFFF">
+
NS_ :
GPIO PINS</span>
+
BA_
! scope="col" style="text-align: left;" style="background:#7acee2;" | <span style="color:#FFFFFF">
+
BA_DEF_
DESCRIPTION </span>
+
BA_DEF_DEF_
! scope="col" style="text-align: left;" style="background:#7acee2;" | <span style="color:#FFFFFF">
+
BA_DEF_DEF_REL_
COLOR </span>
+
BA_DEF_REL_
|-
+
BA_DEF_SGTYPE_
|
+
BA_REL_
* '''D1'''
+
BA_SGTYPE_
|VCC and GND
+
BO_TX_BU_
|POWER
+
BU_BO_REL_
|RED
+
BU_EV_REL_
|-
+
BU_SG_REL_
|
+
CAT_
* '''D2 MOTOR'''
+
CAT_DEF_
|P2.5 and VCC
+
CM_
|RPM
+
ENVVAR_DATA_
|RED
+
EV_DATA_
|-
+
FILTER
|
+
NS_DESC_
* '''D3 MOTOR'''
+
SGTYPE_
|P0.29
+
SGTYPE_VAL_
|Motor Heartbeat
+
SG_MUL_VAL_
|Yellow
+
SIGTYPE_VALTYPE_
|-
+
SIG_GROUP_
|
+
SIG_TYPE_REF_
* '''D4 MOTOR'''
+
SIG_VALTYPE_
|P0.30
+
VAL_
|DC Motor
+
VAL_TABLE_
|Blue
+
 
|-
+
BS_:
|
+
 
* '''D5 MOTOR'''
+
BU_: MASTER BRIDGE MOTOR SENSOR GPS DBG
|P1.19
+
 
|Servo Motor
+
 
|Green
+
BO_ 103 BRIDGE_NODE: 1 BRIDGE
|-
+
SG_ BRIDGE_START_cmd : 0|1@1+ (1,0) [0|1] "" MASTER,MOTOR
|
+
 
* '''D6 BRIDGE'''
+
BO_ 104 CAR_CONTROL: 4 MASTER
|P0.29
+
SG_ MOTOR_DRIVE_cmd : 0|2@1+ (1,0) [0|0] "" MOTOR,BRIDGE
|Bridge Heartbeat
+
SG_ MOTOR_STEER_cmd : 2|15@1+ (0.1,-90.0) [-90|90] "" MOTOR,BRIDGE
|Red
+
SG_ MOTOR_kph : 17|12@1+ (0.01,0) [0.00|20.00] "kph" MOTOR,BRIDGE
|-
+
|
+
BO_ 105 SENSOR_NODE: 5 SENSOR
* '''D7 BRIDGE'''
+
SG_ SENSOR_FRONT_cm : 0|10@1+ (1,0) [0|645] "cm" MASTER,MOTOR,BRIDGE
|P0.30
+
SG_ LIDAR_Obstacle_FRONT : 10|3@1+ (1,0) [0|0] "" MASTER,MOTOR,BRIDGE
|DC Motor
+
SG_ LIDAR_Obstacle_RIGHT : 13|3@1+ (1,0) [0|0] "" MASTER,MOTOR,BRIDGE
|BLUE
+
SG_ LIDAR_Obstacle_LEFT : 16|3@1+ (1,0) [0|0] "" MASTER,MOTOR,BRIDGE
|-
+
SG_ LIDAR_Obstacle_BACK : 19|3@1+ (1,0) [0|0] "" MASTER,MOTOR,BRIDGE
|
+
SG_ LIDAR_Obstacle_BACK_RIGHT : 22|3@1+ (1,0) [0|0] "" MASTER,MOTOR,BRIDGE
* '''D8 GPS'''
+
SG_ LIDAR_Obstacle_BACK_LEFT : 25|3@1+ (1,0) [0|0] "" MASTER,MOTOR,BRIDGE
|P0.30
+
 
|Geographical FIX
+
BO_ 106 MOTOR_NODE: 2 MOTOR
|BLUE
+
SG_ MOTOR_SPEED_kph : 0|12@1+ (0.01,0) [0.00|20.00] "kph" MASTER,BRIDGE
|-
+
|
+
BO_ 107 BRIDGE_CHECKPOINTS: 8 BRIDGE
* '''D9 GPS'''
+
SG_ CHECKPOINT_LAT_deg : 0|28@1+ (0.000001,-90.000000) [-90|90] "Degrees" MASTER,GPS,MOTOR
|P0.29
+
SG_ CHECKPOINT_LONG_deg : 28|29@1+ (0.000001,-180.000000) [-180|180] "Degrees" MASTER,GPS,MOTOR
|Geographical Heartbeat
+
|Yellow
+
BO_ 108 GPS_LOCATION: 8 GPS
|-
+
SG_ CURRENT_LAT_deg : 0|28@1+ (0.000001,-90.000000) [-90|90] "Degrees" MASTER,BRIDGE,MOTOR
|
+
SG_ CURRENT_LONG_deg : 28|29@1+ (0.000001,-180.000000) [-180|180] "Degrees" MASTER,BRIDGE,MOTOR
* '''D10 GPS'''
+
|P1.19
+
BO_ 109 COMPASS: 8 GPS
|Compass Data
+
SG_ CMP_HEADING_deg : 0|12@1+ (0.1,0) [0|359.9] "Degrees" MASTER,BRIDGE,MOTOR
|Green
+
SG_ CMP_BEARING_deg : 12|12@1+ (0.1,0) [0|359.9] "Degrees" MASTER,BRIDGE,MOTOR
|-
+
SG_ CMP_DISTANCE_meters : 24|17@1+ (0.01,0) [0|0] "Meters" MASTER,MOTOR,BRIDGE
|
+
* '''D11 SENSOR'''
+
BO_ 110 MASTER_HEARTBEAT: 1 MASTER
| P0.29
+
SG_ MASTER_hbt : 0|1@1+ (1,0) [0|1] "" SENSOR,MOTOR,BRIDGE,GPS
| Sensor Heartbeat
+
 
| Green
+
BO_ 111 SENSOR_HEARTBEAT: 1 SENSOR
|-
+
SG_ SENSOR_hbt : 0|1@1+ (1,0) [0|1] "" MASTER
|
+
 
* '''D12 SENSOR'''
+
BO_ 112 MOTOR_HEARTBEAT: 1 MOTOR
| P0.30
+
SG_ MOTOR_hbt : 0|1@1+ (1,0) [0|1] "" MASTER
| Left Obstacle
+
     
| Yellow
+
BO_ 113 GPS_HEARTBEAT: 1 GPS
|-
+
SG_ GPS_hbt : 0|1@1+ (1,0) [0|1] "" MASTER
|
+
   
* '''D13 SENSOR'''
+
BO_ 114 BRIDGE_HEARTBEAT: 1 BRIDGE
| P1.19
+
SG_ BRIDGE_hbt : 0|1@1+ (1,0) [0|1] "" MASTER
| Right Obstacle
+
 
| Blue
+
BO_ 115 SENSOR_DEBUG: 1 SENSOR
|-
+
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
* '''D14 SENSOR'''
+
SG_ IO_DEBUG_CAN_TX : 2|1@1+ (1,0) [0|0] "" DBG
| P1.20
+
SG_ IO_DEBUG_bus_off : 3|1@1+ (1,0) [0|0] "" DBG
| Front Obstacle
+
| Green
+
BO_ 116 MOTOR_DEBUG: 2 MOTOR
|-
+
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
* '''D15 SENSOR'''
+
SG_ IO_DEBUG_RPM_kph : 2|12@1+ (0.01,0) [0.00|20.00] "kph" DBG
| P1.19
+
| Right Obstacle
+
BO_ 117 MASTER_DEBUG: 1 MASTER
| Blue
+
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_drive_mode : 2|1@1+ (1,0) [0|0] "" DBG
* '''D16 MASTER'''
+
SG_ IO_DEBUG_HBT_FROM_ALL_CONTR : 3|1@1+ (1,0) [0|0] "" DBG
| P0.29
+
 
| Sensor Heartbeat
+
BO_ 118 GPS_DEBUG: 1 GPS
| Red
+
SG_ IO_DEBUG_CAN_init : 0|1@1+ (1,0) [0|0] "" DBG
|-
+
SG_ IO_DEBUG_HBT_Transmit : 1|1@1+ (1,0) [0|0] "" DBG
|
+
SG_ IO_DEBUG_bus_off : 2|1@1+ (1,0) [0|0] "" DBG
* '''D17 MASTER'''
+
SG_ IO_DEBUG_GPS_rx : 3|1@1+ (1,0) [0|0] "" DBG
| P0.30
+
SG_ IO_DEBUG_GPS_Fix : 4|1@1+ (1,0) [0|0] "" DBG
| Motor Heartbeat
+
SG_ IO_DEBUG_Compass_Rx : 5|1@1+ (1,0) [0|0] "" DBG
| Green
+
 
|-
+
BO_ 119 BRIDGE_DEBUG: 1 BRIDGE
|
+
SG_ IO_DEBUG_CAN_init : 0|1@1+ (1,0) [0|0] "" DBG
* '''D18 MASTER'''
+
SG_ IO_DEBUG_HBT_Transmit : 1|1@1+ (1,0) [0|0] "" DBG
| P1.19
+
SG_ IO_DEBUG_bus_off : 2|1@1+ (1,0) [0|0] "" DBG
| Bridge Heartbeat
+
SG_ IO_DEBUG_Connected : 3|1@1+ (1,0) [0|0] "" DBG
| Yellow
+
SG_ IO_DEBUG_Bridge_rx : 4|1@1+ (1,0) [0|0] "" DBG
|-
+
 
|
+
CM_ BU_ MASTER "The master controller driving the car";
* '''D19 MASTER'''
+
CM_ BU_ MOTOR "The motor controller of the car";
| P1.20
+
CM_ BU_ SENSOR "The sensor controller of the car";
| Geographical Heartbeat
+
CM_ BU_ BRIDGE "The bridge controller of the car";
| Blue
+
CM_ BU_ GPS "The gps controller of the car";
|-
+
CM_ BU_ DBG "The debug node of the car";
<BR/>
+
CM_ BO_ 100 "Sync message used to synchronize the controllers";
  
=='''DBC File'''==
+
BA_DEF_ "BusType" STRING ;
A Link to the DBC file that defines the CAN communication of the system is as follows:
+
BA_DEF_ BO_ "GenMsgCycleTime" INT 0 0;
[https://gitlab.com/tech-savycmpe243/cmpe243_techsavy_rc_car/blob/master/PROJ_DBC_File/243_techSavvy.dbc DBC link on GitLab]
+
BA_DEF_ SG_ "FieldType" STRING ;
<br>
 
  
DBC is a format that enables fewer hassles while developing code to either interpret data received or send data over the CAN bus. This project used DBC effectively.
+
BA_DEF_DEF_ "BusType" "CAN";
 +
BA_DEF_DEF_ "FieldType" "";
 +
BA_DEF_DEF_ "GenMsgCycleTime" 0;
 +
 
 +
BA_ "GenMsgCycleTime" BO_ 103 100;
 +
BA_ "GenMsgCycleTime" BO_ 104 100;
 +
BA_ "GenMsgCycleTime" BO_ 105 100;
 +
BA_ "GenMsgCycleTime" BO_ 106 100;
 +
BA_ "GenMsgCycleTime" BO_ 107 100;
 +
BA_ "GenMsgCycleTime" BO_ 108 100;
 +
BA_ "GenMsgCycleTime" BO_ 109 100;
 +
BA_ "GenMsgCycleTime" BO_ 110 100;
 +
BA_ "GenMsgCycleTime" BO_ 111 100;
 +
BA_ "GenMsgCycleTime" BO_ 112 100;
 +
BA_ "GenMsgCycleTime" BO_ 113 100;
 +
BA_ "GenMsgCycleTime" BO_ 114 100;
 +
BA_ "GenMsgCycleTime" BO_ 115 100;
 +
BA_ "GenMsgCycleTime" BO_ 116 100;
 +
BA_ "GenMsgCycleTime" BO_ 117 100;
 +
BA_ "FieldType" SG_ 104 MOTOR_DRIVE_cmd "MOTOR_DRIVE_cmd";
  
Shown below is the DBC implementation for this project.
 
<pre>
 
VERSION ""
 
  
NS_ :
+
VAL_ 104 MOTOR_DRIVE_cmd 2 "MOTOR_STOP" 1 "MOTOR_REV" 0 "MOTOR_FORWARD" ;
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_: MASTER BRIDGE MOTOR SENSOR GPS DBG
+
</pre>
  
 +
A screenshot of the Bus Master Application is as shown below:
 +
[[File:Busmaster.jpg|800px|thumb|center|]]
 +
<HR>
 +
<BR/>
  
BO_ 103 BRIDGE_NODE: 1 BRIDGE
+
=='''3D printing models''' ==
  SG_ BRIDGE_START_cmd : 0|1@1+ (1,0) [0|1] "" MASTER,MOTOR
+
We used a 3D mount model to mount the ultrasonic sensor and compass. After testing the ultrasonic sensor at different angles we noticed that best results are when sensors are mounted at 70 degrees with respect to the ground. Most important thing to consider was the mount should be able to adjust tilt of the sensors since we were receiving lot of reflection from the ground. So in order to satisfy that requirement mount is constructed from two parts, the stand and part that holds the sensor what gave us freedom to test sensors positioning. We used the 3D mount design from Thingiverse.
  
BO_ 104 CAR_CONTROL: 4 MASTER
+
Since we needed to keep the Compass sensor away from DC Motor's interference, we decided to keep the compass at certain height above the PCB. So we used 3D printing to print the support plate with the mounting holes of same dimension as M3X10 screw standoffs.
SG_ MOTOR_DRIVE_cmd : 0|2@1+ (1,0) [0|0] "" MOTOR,BRIDGE
 
SG_ MOTOR_STEER_cmd : 2|15@1+ (0.1,-90.0) [-90|90] "" MOTOR,BRIDGE
 
SG_ MOTOR_kph : 17|12@1+ (0.01,0) [0.00|20.00] "kph" MOTOR,BRIDGE
 
 
BO_ 105 SENSOR_NODE: 5 SENSOR
 
SG_ SENSOR_FRONT_cm : 0|10@1+ (1,0) [0|645] "cm" MASTER,MOTOR,BRIDGE
 
SG_ LIDAR_Obstacle_FRONT : 10|3@1+ (1,0) [0|0] "" MASTER,MOTOR,BRIDGE
 
SG_ LIDAR_Obstacle_RIGHT : 13|3@1+ (1,0) [0|0] "" MASTER,MOTOR,BRIDGE
 
SG_ LIDAR_Obstacle_LEFT : 16|3@1+ (1,0) [0|0] "" MASTER,MOTOR,BRIDGE
 
SG_ LIDAR_Obstacle_BACK : 19|3@1+ (1,0) [0|0] "" MASTER,MOTOR,BRIDGE
 
SG_ LIDAR_Obstacle_BACK_RIGHT : 22|3@1+ (1,0) [0|0] "" MASTER,MOTOR,BRIDGE
 
SG_ LIDAR_Obstacle_BACK_LEFT : 25|3@1+ (1,0) [0|0] "" MASTER,MOTOR,BRIDGE
 
  
BO_ 106 MOTOR_NODE: 2 MOTOR
+
[[File:Ultrasonic_mount.jpg|300px|thumb|left|Ultrasonic Sensor Mount]]
SG_ MOTOR_SPEED_kph : 0|12@1+ (0.01,0) [0.00|20.00] "kph" MASTER,BRIDGE
+
[[File:Actual_mount.jpg|160px|thumb|right|Actual Mount]]
+
 
BO_ 107 BRIDGE_CHECKPOINTS: 8 BRIDGE
+
 
SG_ CHECKPOINT_LAT_deg : 0|28@1+ (0.000001,-90.000000) [-90|90] "Degrees" MASTER,GPS,MOTOR
+
[[File:Compass_mount.JPG|280px|thumb|center|Compass Mount]]
SG_ CHECKPOINT_LONG_deg : 28|29@1+ (0.000001,-180.000000) [-180|180] "Degrees" MASTER,GPS,MOTOR
+
 
+
=='''Sensor Node'''==
BO_ 108 GPS_LOCATION: 8 GPS
+
We used 2 sensor modules to achieve accurate and reliable obstacle avoidance system.<br>
SG_ CURRENT_LAT_deg : 0|28@1+ (0.000001,-90.000000) [-90|90] "Degrees" MASTER,BRIDGE,MOTOR
+
'''1. Lidar''' - Main controller to detect obstacle. Giving 360-degree view with a range up to 6 meters in distance.<br>
SG_ CURRENT_LONG_deg : 28|29@1+ (0.000001,-180.000000) [-180|180] "Degrees" MASTER,BRIDGE,MOTOR
+
*RPLidar works on a mechanism known as laser triangulation ranging principle. The system measures distance data in more than 2000 times’ per second and with high-resolution distance output. RPLIDAR emits modulated infrared laser signal and the laser signal is then reflected by the object to be detected. The returning signal is sampled by vision acquisition system in RPLIDAR A1 and the DSP embedded in RPLIDAR starts processing the sample data and output distance value and angle value between object and RPLIDAR A1 through the communication interface.<br>
+
[[File:Lidar_RPLidar_working_schematic.png|500x900px|thumb|center|Lidar Working Schematic]]
BO_ 109 COMPASS: 8 GPS
+
 
SG_ CMP_HEADING_deg : 0|12@1+ (0.1,0) [0|359.9] "Degrees" MASTER,BRIDGE,MOTOR
+
'''2. Ultrasonic Sensor (Maxbotix LV-MaxSonar-EZ0)''' - One Ultrasonic sensor with a maximum range of 600 cm was used to detect very small objects at the front that Lidar might miss because of it's leveled placement.<br>
SG_ CMP_BEARING_deg : 12|12@1+ (0.1,0) [0|359.9] "Degrees" MASTER,BRIDGE,MOTOR
+
[[File:ultrasonicbeam.png|100px|thumb|right|ultrasonic beam]]
SG_ CMP_DISTANCE_meters : 24|17@1+ (0.01,0) [0|0] "Meters" MASTER,MOTOR,BRIDGE
+
*Ultrasonic sensor uses a high-frequency beam to detect an object. It first throws light and reads the time taken for light to receive back, depending on the time calculated, it identifies the obstacle. It calibrates after it's first to read cycle, then it can continuously read data of light. The beam depending on the range is shown in figure.<br>
+
 
BO_ 110 MASTER_HEARTBEAT: 1 MASTER
+
====Sensor Node Code====
SG_ MASTER_hbt : 0|1@1+ (1,0) [0|1] "" SENSOR,MOTOR,BRIDGE,GPS
+
[https://gitlab.com/tech-savycmpe243/cmpe243_techsavy_rc_car/tree/master/Sensor_Controller_Module GitLab link to Sensor Code]
 
+
 
BO_ 111 SENSOR_HEARTBEAT: 1 SENSOR
+
=== Hardware Design ===
SG_ SENSOR_hbt : 0|1@1+ (1,0) [0|1] "" MASTER
+
*The Lidar is communicating with SJOne board through UART, we have used UART 2 here as shown in Pin config below. <br>
 
+
*Ultrasonic Sensor is simple Interrupt based, hence it connected through GPIO pins of SJOne board as shown in diagram.<br>
BO_ 112 MOTOR_HEARTBEAT: 1 MOTOR
 
SG_ MOTOR_hbt : 0|1@1+ (1,0) [0|1] "" MASTER
 
     
 
BO_ 113 GPS_HEARTBEAT: 1 GPS
 
SG_ GPS_hbt : 0|1@1+ (1,0) [0|1] "" MASTER
 
   
 
BO_ 114 BRIDGE_HEARTBEAT: 1 BRIDGE
 
SG_ BRIDGE_hbt : 0|1@1+ (1,0) [0|1] "" MASTER
 
  
BO_ 115 SENSOR_DEBUG: 1 SENSOR
+
[[File:TechSavy_Lidar_pincon.png|500x900px|thumb|center|Sensor Pin connection]]
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_CAN_TX : 2|1@1+ (1,0) [0|0] "" DBG
 
SG_ IO_DEBUG_bus_off : 3|1@1+ (1,0) [0|0] "" DBG
 
 
BO_ 116 MOTOR_DEBUG: 2 MOTOR
 
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_RPM_kph : 2|12@1+ (0.01,0) [0.00|20.00] "kph" DBG
 
 
BO_ 117 MASTER_DEBUG: 1 MASTER
 
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_drive_mode : 2|1@1+ (1,0) [0|0] "" DBG
 
SG_ IO_DEBUG_HBT_FROM_ALL_CONTR : 3|1@1+ (1,0) [0|0] "" DBG
 
  
BO_ 118 GPS_DEBUG: 1 GPS
+
*Figure shows the usage of 4 LEDS and LCD display to notify us the position of obstacle.<br>
SG_ IO_DEBUG_CAN_init : 0|1@1+ (1,0) [0|0] "" DBG
 
SG_ IO_DEBUG_HBT_Transmit : 1|1@1+ (1,0) [0|0] "" DBG
 
SG_ IO_DEBUG_bus_off : 2|1@1+ (1,0) [0|0] "" DBG
 
SG_ IO_DEBUG_GPS_rx : 3|1@1+ (1,0) [0|0] "" DBG
 
SG_ IO_DEBUG_GPS_Fix : 4|1@1+ (1,0) [0|0] "" DBG
 
SG_ IO_DEBUG_Compass_Rx : 5|1@1+ (1,0) [0|0] "" DBG
 
  
BO_ 119 BRIDGE_DEBUG: 1 BRIDGE
+
[[File:techsavy_lidar_led.jpg|300px|thumb|left|LED indication]]
SG_ IO_DEBUG_CAN_init : 0|1@1+ (1,0) [0|0] "" DBG
+
[[File:TechSavy_sensor_lcd_screen.jpeg|300px|thumb|center|LCD screen showing the value of track of obstacle at respective direction]]
SG_ IO_DEBUG_HBT_Transmit : 1|1@1+ (1,0) [0|0] "" DBG
 
SG_ IO_DEBUG_bus_off : 2|1@1+ (1,0) [0|0] "" DBG
 
SG_ IO_DEBUG_Connected : 3|1@1+ (1,0) [0|0] "" DBG
 
SG_ IO_DEBUG_Bridge_rx : 4|1@1+ (1,0) [0|0] "" DBG
 
  
CM_ BU_ MASTER "The master controller driving the car";
+
====Implementation====
CM_ BU_ MOTOR "The motor controller of the car";
+
=====<font color="FUCHSIA"><B>'''Ultrasonic'''</B></font>=====
CM_ BU_ SENSOR "The sensor controller of the car";
+
LV Maxsonar ultrasonic sensor is used at the very front of the RC car to provide wide range sonar detection ranging from 0 to 645 cm. It supports LiDAR sensor to detect very small obstacles like stone that can hinder car from moving forward. so we have purposefully mounted it at a lower level than LiDAR.
CM_ BU_ BRIDGE "The bridge controller of the car";
+
 
CM_ BU_ GPS "The gps controller of the car";
+
=====<font color="FUCHSIA"><B><font color="FUCHSIA">'''LiDAR'''</font></B></font>=====
CM_ BU_ DBG "The debug node of the car";
+
RPLidar works on UART. We have used UART 2 of SJOne Board to establish communication between them.
CM_ BO_ 100 "Sync message used to synchronize the controllers";
 
  
BA_DEF_ "BusType" STRING ;
+
*Figure shows the several operation provided by RPLidar for better performance and reliable data.<br>
BA_DEF_ BO_ "GenMsgCycleTime" INT 0 0;
+
[[File: lidar_operation.png|700px|thumb|center| Various Operations of RPLidar]]<br>
BA_DEF_ SG_ "FieldType" STRING ;
 
  
BA_DEF_DEF_ "BusType" "CAN";
+
'''Algorithm to establish communication through UART'''
BA_DEF_DEF_ "FieldType" "";
+
* In order to start the scanning of Lidar, first send the 0X20 via <code>uart2.putchar(0x20)</code>. Before that, we can check the health status of RPLidar by sending 0x52. It waits for some time (timeout = 500ms), and if return status is not true throws error indicating Lidar is not initialized properly and hence it gets reset. <br>
BA_DEF_DEF_ "GenMsgCycleTime" 0;
 
  
BA_ "GenMsgCycleTime" BO_ 103 100;
+
* As soon as correct scan command is received by Lidar, it starts sending data frames continuously on UART. The frame consists of 5 bytes including the start bit, Angle, quality and distance, which are useful to identify the exact position of obstacle.<br>
BA_ "GenMsgCycleTime" BO_ 104 100;
 
BA_ "GenMsgCycleTime" BO_ 105 100;
 
BA_ "GenMsgCycleTime" BO_ 106 100;
 
BA_ "GenMsgCycleTime" BO_ 107 100;
 
BA_ "GenMsgCycleTime" BO_ 108 100;
 
BA_ "GenMsgCycleTime" BO_ 109 100;
 
BA_ "GenMsgCycleTime" BO_ 110 100;
 
BA_ "GenMsgCycleTime" BO_ 111 100;
 
BA_ "GenMsgCycleTime" BO_ 112 100;
 
BA_ "GenMsgCycleTime" BO_ 113 100;
 
BA_ "GenMsgCycleTime" BO_ 114 100;
 
BA_ "GenMsgCycleTime" BO_ 115 100;
 
BA_ "GenMsgCycleTime" BO_ 116 100;
 
BA_ "GenMsgCycleTime" BO_ 117 100;
 
BA_ "FieldType" SG_ 104 MOTOR_DRIVE_cmd "MOTOR_DRIVE_cmd";
 
  
 +
[[File:RPLidar_data_frame.png|500px|thumb|center|]]
  
VAL_ 104 MOTOR_DRIVE_cmd 2 "MOTOR_STOP" 1 "MOTOR_REV" 0 "MOTOR_FORWARD" ;
+
* This data is processed and divided into tracks of 25 cm each. <br>
  
 +
* By looking at the track, we choose the sector value which depends on angle detected. Below figure shows the division of angle for respective sector value.<br>
 +
[[File:TechSavy_Lidar_angle.png|700px|thumb|center|Figure shows the division of angles]]
 +
* The obstacle information is sent to Master Node through CAN.<br>
  
</pre>
+
=== Software Design ===
 
+
====<font color="FUCHSIA"><B>'''Ultrasonic'''</B></font>====
A screenshot of the Bus Master Application is as shown below:
+
*It works with the help of interrupt.
[[File:Busmaster.jpg|800px|thumb|center|]]
+
* After configuring GPIO pins as RX and TX, set RX pin high.
<HR>
+
* PW pin gets the input, identify the type of interrupt
<BR/>
+
**Rising edge interrupt.
 +
**Falling edge interrupt
 +
*Calculate distance to obstacle,
 +
** <code>ultrasonic_data.distance = (stop_time - start_time)/147; </code>
  
=='''3D printing models''' ==
+
====<font color="FUCHSIA"><B><font color="FUCHSIA">'''LiDAR'''</font></B></font>====
We used a 3D mount model to mount the ultrasonic sensor and compass. After testing the ultrasonic sensor at different angles we noticed that best results are when sensors are mounted at 70 degrees with respect to the ground. Most important thing to consider was the mount should be able to adjust tilt of the sensors since we were receiving lot of reflection from the ground. So in order to satisfy that requirement mount is constructed from two parts, the stand and part that holds the sensor what gave us freedom to test sensors positioning. We used the 3D mount design from Thingiverse.
+
Below diagram shows the code flow of sensor module. A separate task was used to send sensor data over CAN, which continuously sends data in while(1) loop.
 +
[[File:TechSavy_Sensor_flowchart.png|770x770px|center|Sensor Flowchart]]
  
Since we needed to keep the Compass sensor away from DC Motor's interference, we decided to keep the compass at certain height above the PCB. So we used 3D printing to print the support plate with the mounting holes of same dimension as M3X10 screw standoffs.
+
====CAN DBC Messages Send from Sensor====
  
[[File:Ultrasonic_mount.jpg|300px|thumb|left|Ultrasonic Sensor Mount]]
+
  BO_ 105 SENSOR_NODE: 5 SENSOR
[[File:Actual_mount.jpg|200px|thumb|right|Actual Mount]]
+
    SG_ SENSOR_FRONT_cm : 0|10@1+ (1,0) [0|645] "cm" MASTER,MOTOR,BRIDGE
 +
    SG_ LIDAR_Obstacle_FRONT : 10|3@1+ (1,0) [0|0] "" MASTER,MOTOR,BRIDGE
 +
    SG_ LIDAR_Obstacle_RIGHT : 13|3@1+ (1,0) [0|0] "" MASTER,MOTOR,BRIDGE
 +
    SG_ LIDAR_Obstacle_LEFT : 16|3@1+ (1,0) [0|0] "" MASTER,MOTOR,BRIDGE
 +
    SG_ LIDAR_Obstacle_BACK : 19|3@1+ (1,0) [0|0] "" MASTER,MOTOR,BRIDGE
 +
    SG_ LIDAR_Obstacle_BACK_RIGHT : 22|3@1+ (1,0) [0|0] "" MASTER,MOTOR,BRIDGE
 +
    SG_ LIDAR_Obstacle_BACK_LEFT : 25|3@1+ (1,0) [0|0] "" MASTER,MOTOR,BRIDGE
  
 +
===='''LED Blinking signals for SENSOR CONTROLLER ON CAR'''====
 +
* RED LED ON: MASTER HEARTBEAT STATUS on CAR
 +
* BLUE LED ON: Obstacle detected at front of CAR
 +
* Rightmost GREEN LED ON: Obstacle detected at right of CAR
 +
* YELLOW LED ON: Obstacle detected at back of CAR
 +
* Leftmost GREEN LED ON: Obstacle detected at left of CAR.
  
[[File:Compass_mount.JPG|280px|thumb|center|Compass Mount]]
+
=== Technical Challenges ===
 
+
====<font color="FUCHSIA"><B>'''Ultrasonic'''</B></font>====
=='''Sensor Node'''==
+
*When mounted initially on CAR, ultrasonic was giving sometimes faulty readings as it was detecting ground as and obstacle.
We used 2 sensor modules to achieve accurate and reliable obstacle avoidance system.<br>
+
**We designed a 3D mount for it and adjusted it on such a angle that it gives perfect readings.
'''1. Lidar''' - Main controller to detect obstacle. Giving 360-degree view with a range up to 6 meters in distance.<br>
+
*Initialization issue: Sometimes on power-up we noticed that Ultrasonic sensor was giving faulty readings(it was getting stuck on some fixed value).
*RPLidar works on a mechanism known as laser triangulation ranging principle. The system measures distance data in more than 2000 times’ per second and with high-resolution distance output. RPLIDAR emits modulated infrared laser signal and the laser signal is then reflected by the object to be detected. The returning signal is sampled by vision acquisition system in RPLIDAR A1 and the DSP embedded in RPLIDAR starts processing the sample data and output distance value and angle value between object and RPLIDAR A1 through the communication interface.<br>
+
**After reading the datasheet accurately, I found that it calibrates itself during the first read cycle and so the obstacle should be at least 14 inches far from the sensor.  
[[File:Lidar_RPLidar_working_schematic.png|500x900px|thumb|center|Lidar Working Schematic]]
+
*Ultrasonic Failure - When the CAR got crashed, Ultrasonic sensor failed and started giving incorrect data.
 +
**We replaced it's wired to get it working.<br>
  
'''2. Ultrasonic Sensor (Maxbotix LV-MaxSonar-EZ0)''' - One Ultrasonic sensor with a maximum range of 600 cm was used to detect very small objects at the front that Lidar might miss because of it's leveled placement.<br>
+
====<font color="FUCHSIA"><B><font color="FUCHSIA">'''LiDAR'''</font></B></font>====
[[File:ultrasonicbeam.png|100px|thumb|right|ultrasonic beam]]
+
* Identifying obstacle data and separating it.
*Ultrasonic sensor uses a high-frequency beam to detect an object. It first throws light and reads the time taken for light to receive back, depending on the time calculated, it identifies the obstacle. It calibrates after it's first to read cycle, then it can continuously read data of light. The beam depending on the range is shown in figure.<br>
+
** Initially I lost a lot of time in figuring out the data frame as it consists of quality, angle, distance and start bit.
 
+
** Dividing the frame bits appropriately and storing it separately in struct variables resolved the issue. Also after that depending on the angle, every 360 times data was fetched in a loop to cover each and every angle value.
====Sensor Node Code====
+
* Task overrun because of receiving a large number of data continuously over UART.
[https://gitlab.com/tech-savycmpe243/cmpe243_techsavy_rc_car/tree/master/Sensor_Controller_Module GitLab link to Sensor Code]
+
** Used a separate task, that receives data continuously in a loop, i.e while(1).
 +
** Instead of receiving whole data in a single frame, took data character by character in a for loop 360 times, to get the value of obstacle at each degree.
 +
* Angle detection problem - When large angles were taken, for example, 30 degrees on the right, it was detecting nearer objects correctly but far objects were getting detected in some other range (for example in front instead of right) of angle because of angle spread. I divided the range into 10 degrees each and store it in the same variable to send it over CAN.<br> For example, to get 30 degrees in right, 0-10,10-20 & 20-30 values are taken.
 +
* Received variable initialization problem.
 +
** I didn't initialize the character variable to get data from UART to 0 and hence it was taking garbage value.<br> Thanks to Preet, at time of my code review he pointed out this problem and later I checked it with Unit Testing.
 +
* Some bugs here and there in the code.
 +
** I identified and resolved a few bugs after Unit testing the code.
 +
* Delay in sending data because of large CAN buffer size.
 +
** We were facing this issue with master, motor and sensor communication. The response time was slow as data was getting accumulated before sending because of large buffer size taken.
 +
 
 +
<BR/>
 +
 
 +
=='''Motor Controller'''==
 +
Motor Controller is responsible to control the DC and Servo Motor, RPM Sensor measurements and LCD control. The motor control logic controls the steering and the speed of the vehicle using a servo and DC motor respectively based on the CAR_CONTROL_t CAN message from the master. It takes input from RPM sensor as a feedback for maintaining a constant speed and based on the RPM sensor reading, a PID loop calculates duty-cycle for PWM signal which are then given to DC motor. Based on other can messages from the sensor controller, geo controller and bridge controller, motor controller processes and communicates the information to the LCD by refreshing the data periodically in 10Hz function.
  
 
=== Hardware Design ===
 
=== Hardware Design ===
*The Lidar is communicating with SJOne board through UART, we have used UART 2 here as shown in Pin config below. <br>
+
The hardware interface details of '''MOTOR Module''' with SJOne board are given below:
*Ultrasonic Sensor is simple Interrupt based, hence it connected through GPIO pins of SJOne board as shown in diagram.<br>
+
 
 +
[[ File: RPM Sensor, DC and Servo Motor Hardware Design.jpeg|600px|thumb|left|RPM Sensor, DC and Servo Motor Hardware Interfacing]]
 +
[[ File: LCD.JPG |520px|thumb|center|LCD Hardware Connections]]
 +
 
 +
 
 +
 
  
[[File:TechSavy_Lidar_pincon.png|500x900px|thumb|center|Sensor Pin connection]]
 
  
*Figure shows the usage of 4 LEDS and LCD display to notify us the position of obstacle.<br>
 
  
{|
 
|
 
|
 
|
 
|
 
|
 
|[[File:techsavy_lidar_led.jpg|300px|thumb|center|LED indication]]
 
|
 
|
 
|
 
|
 
|[[File:TechSavy_sensor_lcd_screen.jpeg|300px|thumb|right|LCD screen showing the value of track of obstacle at respective direction]]
 
|
 
|}
 
  
====Implementation====
 
=====<font color="FUCHSIA"><B>'''Ultrasonic'''</B></font>=====
 
LV Maxsonar ultrasonic sensor is used at the very front of the RC car to provide wide range sonar detection ranging from 0 to 645 cm. It supports LiDAR sensor to detect very small obstacles like stone that can hinder car from moving forward. so we have purposefully mounted it at a lower level than LiDAR.
 
  
=====<font color="FUCHSIA"><B><font color="FUCHSIA">'''LiDAR'''</font></B></font>=====
+
=== Hardware Interface ===
RPLidar works on UART. We have used UART 2 of SJOne Board to establish communication between them.
 
  
*Figure shows the several operation provided by RPLidar for better performance and reliable data.<br>
+
====Electronic Speed Controller (ESC)====
[[File: lidar_operation.png|700px|thumb|center| Various Operations of RPLidar]]<br>
+
We made use of the Traxxas ESC XL-05 which comes with the RC car. ESC stands for Electronic Speed Control. It is used to control the DC motor using PWM signals from the controller. It powers up when we connect a LiPo or NiMH battery of 7.4v. The ESC has a dc-to-dc converter which converts 7.4v to 6v and provides it to DC motor. It can provide high current to the power hungry DC motors running at faster speeds. It has an LED and a button which is used for calibration and setting different modes for the car.
 +
 +
[[File:CMPE243 F17 nano ESC.jpg|220px|thumb|right|Traxxas ESC XL5]]
  
'''Algorithm to establish communication through UART'''
+
====DC Motor====
* In order to start the scanning of Lidar, first send the 0X20 via <code>uart2.putchar(0x20)</code>. Before that, we can check the health status of RPLidar by sending 0x52. It waits for some time (timeout = 500ms), and if return status is not true throws error indicating Lidar is not initialized properly and hence it gets reset. <br>
 
  
* As soon as correct scan command is received by Lidar, it starts sending data frames continuously on UART. The frame consists of 5 bytes including the start bit, Angle, quality and distance, which are useful to identify the exact position of obstacle.<br>
+
[[File:CMPE_S19_techsavy_dc.jpg‎|350px|thumb|right|Traxxas DC Motor]]
 
+
The DC motor is controlled using the ESC which get PWM pulses for controlling it. A PWM signal wire is connected to the microcontroller and the required current is provided by the LiPo battery and the ESC. Below table shows  the LED functionality implemented in PCB for all the controllers.
[[File:RPLidar_data_frame.png|500px|thumb|center|]]
+
{| class="wikitable"
 +
|+ DC Motor Pin Connection
 +
|-
 +
! scope="col"| S.No
 +
! scope="col"| Wires - DC Motor
 +
! scope="col"| Description
 +
|-
 +
! scope="row"| 1.
 +
| Positive Wire (already Connected)
 +
| Positive Terminal
 +
|-
 +
! scope="row"| 2.  
 +
| Negative Wire (already Connected)
 +
| Negative terminal
 +
|-
 +
|}
  
* This data is processed and divided into tracks of 25 cm each. <br>
+
The DC motor is controlled using PWM at 100Hz.
  
* By looking at the track, we choose the sector value which depends on angle detected. Below figure shows the division of angle for respective sector value.<br>
+
{| class="wikitable"
[[File:TechSavy_Lidar_angle.png|700px|thumb|center|Figure shows the division of angles]]
+
|+ DC MOTOR Configuration
* The obstacle information is sent to Master Node through CAN.<br>
+
|-
 
+
! Operation !! Pulse Width Range(ms) !! Duty-cycle(%)
=== Software Design ===
+
|-
====<font color="FUCHSIA"><B>'''Ultrasonic'''</B></font>====
+
| FORWARD      || 1.51 - 2.00    || 15.1 - 20.0     
*It works with the help of interrupt.  
+
|-
* After configuring GPIO pins as RX and TX, set RX pin high.
+
| STOP      || 1.50    || 15.0
* PW pin gets the input, identify the type of interrupt
+
|-
**Rising edge interrupt.
+
| REVERSE      || 1.00 - 1.49    || 10.0 - 14.9
**Falling edge interrupt
+
|}
*Calculate distance to obstacle,
 
** <code>ultrasonic_data.distance = (stop_time - start_time)/147; </code>
 
  
====<font color="FUCHSIA"><B><font color="FUCHSIA">'''LiDAR'''</font></B></font>====
 
Below diagram shows the code flow of sensor module. A separate task was used to send sensor data over CAN, which continuously sends data in while(1) loop.
 
[[File:TechSavy_Sensor_flowchart.png|770x770px|center|Sensor Flowchart]]
 
  
====CAN DBC Messages Send from Sensor====
+
'''NOTE''': Before using the Traxxas ESC to give PWM signal to DC motor calibrate it by going to this website:<br>
 +
:https://traxxas.com/support/Programming-Your-Traxxas-Electronic-Speed-Control<br>
  
  BO_ 105 SENSOR_NODE: 5 SENSOR
+
:The ESC must be given a pulse of 1.5ms when we turn it on or else the DC motor won't respond to PWM pulses.<br>
    SG_ SENSOR_FRONT_cm : 0|10@1+ (1,0) [0|645] "cm" MASTER,MOTOR,BRIDGE
+
:Step 1: Give 2.00ms on-time pulses when LED blinks red once.<br>
    SG_ LIDAR_Obstacle_FRONT : 10|3@1+ (1,0) [0|0] "" MASTER,MOTOR,BRIDGE
+
:Step 2: Give 1.50ms on-time pulses when LED blinks red twice.<br>
    SG_ LIDAR_Obstacle_RIGHT : 13|3@1+ (1,0) [0|0] "" MASTER,MOTOR,BRIDGE
+
:Step 3: Give 1.00ms on-time pulses and the LED color changes from red to green showing that the calibration was successful.<br>
    SG_ LIDAR_Obstacle_LEFT : 16|3@1+ (1,0) [0|0] "" MASTER,MOTOR,BRIDGE
 
    SG_ LIDAR_Obstacle_BACK : 19|3@1+ (1,0) [0|0] "" MASTER,MOTOR,BRIDGE
 
    SG_ LIDAR_Obstacle_BACK_RIGHT : 22|3@1+ (1,0) [0|0] "" MASTER,MOTOR,BRIDGE
 
    SG_ LIDAR_Obstacle_BACK_LEFT : 25|3@1+ (1,0) [0|0] "" MASTER,MOTOR,BRIDGE
 
  
===='''LED Blinking signals for SENSOR CONTROLLER ON CAR'''====
+
====Servo Motor====
* RED LED ON: MASTER HEARTBEAT STATUS on CAR
+
[[File:CMPE243_F17_nano_servo.jpg ‎|200px|thumb|right|Traxxas Servo Motor]]
* BLUE LED ON: Obstacle detected at front of CAR
+
The direction the vehicle's front wheels turn is dependent on the servo motor in the vehicle. Based on various PWM signals, the servo steers the front wheels of the vehicle in the left and right direction. The servo has 3 wires of which one is for the PWM input signal whereas the other two are to power up the servo. We powered our servo motor using the 6v power supply from the battery elimination circuit present in the ESC so that a single switch to turn on and off both the servo and DC motor. PWM signals to control the servo is provided by the motor controller. Based on the PWM signal from the SJOne board, the
* Rightmost GREEN LED ON: Obstacle detected at right of CAR
+
shaft shall be rotated to a certain degree left or right
* YELLOW LED ON: Obstacle detected at back of CAR
 
* Leftmost GREEN LED ON: Obstacle detected at left of CAR.
 
  
=== Technical Challenges ===
+
{| class="wikitable"
====<font color="FUCHSIA"><B>'''Ultrasonic'''</B></font>====
+
|+ Servo Motor Pin Connection
*When mounted initially on CAR, ultrasonic was giving sometimes faulty readings as it was detecting ground as and obstacle.
+
|-
**We designed a 3D mount for it and adjusted it on such a angle that it gives perfect readings.
+
! scope="col"| S.No
*Initialization issue: Sometimes on power-up we noticed that Ultrasonic sensor was giving faulty readings(it was getting stuck on some fixed value).
+
! scope="col"| Wires - Servo Motor
**After reading the datasheet accurately, I found that it calibrates itself during the first read cycle and so the obstacle should be at least 14 inches far from the sensor.
+
! scope="col"| Function
*Ultrasonic Failure - When the CAR got crashed, Ultrasonic sensor failed and started giving incorrect data.
+
|-
**We replaced it's wired to get it working.<br>
+
! scope="row"| 1.
 +
| PWM connected to P2.1
 +
| PWM signal from SJOne board
 +
|-
 +
! scope="row"| 2.
 +
| VCC
 +
| 6V power supply from ESC
 +
|-
 +
! scope="row"| 3.
 +
| Ground
 +
| Common ground to system
 +
|-
 +
|}
 +
 
 +
====RPM Sensor====
 +
[[File:CMPE243_F17_nano_Speed_Sensor.jpg ‎|250px|thumb|right|Traxxas Speed Sensor]]
 +
RPM sensor is used as a feedback element in the PID to maintain a constant speed of the vehicle. The RPM sensor mounts on the rear DC motor shaft compartment with a special assembly also provided by Traxxas. We make use of one magnet and we get one pulse on one wheel rotation The sensor works on the hall effect principle where it provides a current across its terminal when placed in a magnet's field. These pulses are read by the SJOne board and fed to the speed control algorithm. The RPM sensor has 3 wires, the white where are the output wire that provides the pulses to the SJone board and the other wires power the sensor.  
  
====<font color="FUCHSIA"><B><font color="FUCHSIA">'''LiDAR'''</font></B></font>====
+
=====Implementation=====
* Identifying obstacle data and separating it.
+
1. The idea is that every time the motor completes 1 whole revolution, it reaches very close to the sensor. And when the sensor detects the magnet nearby, it sends out a high pulse until the magnet moves away from it. Therefore, upon detecting the X number of a rising edge in Y seconds we can say that rpm was X revolutions/Y seconds.<br>
** Initially I lost a lot of time in figuring out the data frame as it consists of quality, angle, distance and start bit.
+
2. During our initial testing of RPM Sensor with SJOne board, we saw that regardless of whether we bring the magnet close to the sensor or not, the signal voltage was always high. After some trail and errors, we found out that the signal pin(white wire) had to be connected to the VCC(red wire) across a 1K resistor which can act as weak pull down when it detects the magnet.<br>
** Dividing the frame bits appropriately and storing it separately in struct variables resolved the issue. Also after that depending on the angle, every 360 times data was fetched in a loop to cover each and every angle value.
 
* Task overrun because of receiving a large number of data continuously over UART.
 
** Used a separate task, that receives data continuously in a loop, i.e while(1).
 
** Instead of receiving whole data in a single frame, took data character by character in a for loop 360 times, to get the value of obstacle at each degree.
 
* Angle detection problem - When large angles were taken, for example, 30 degrees on the right, it was detecting nearer objects correctly but far objects were getting detected in some other range (for example in front instead of right) of angle because of angle spread. I divided the range into 10 degrees each and store it in the same variable to send it over CAN.<br> For example, to get 30 degrees in right, 0-10,10-20 & 20-30 values are taken.
 
* Received variable initialization problem.
 
** I didn't initialize the character variable to get data from UART to 0 and hence it was taking garbage value.<br> Thanks to Preet, at time of my code review he pointed out this problem and later I checked it with Unit Testing.
 
* Some bugs here and there in the code.
 
** I identified and resolved a few bugs after Unit testing the code.
 
* Delay in sending data because of large CAN buffer size.
 
** We were facing this issue with master, motor and sensor communication. The response time was slow as data was getting accumulated before sending because of large buffer size taken.
 
  
<HR>
+
{| class="wikitable"
<BR/>
+
|+ Speed Sensor Pin Connection
 
+
|-
=='''Motor Controller'''==
+
! scope="col"| S.No
Motor Controller is responsible to control the DC and Servo Motor, RPM Sensor measurements and LCD control. The motor control logic controls the steering and the speed of the vehicle using a servo and DC motor respectively based on the CAR_CONTROL_t CAN message from the master. It takes input from RPM sensor as a feedback for maintaining a constant speed and based on the RPM sensor reading, a PID loop calculates duty-cycle for PWM signal which are then given to DC motor. Based on other can messages from the sensor controller, geo controller and bridge controller, motor controller processes and communicates the information to the LCD by refreshing the data periodically in 10Hz function.
+
! scope="col"| Wires - RPM Sensor
 
+
! scope="col"| Function
=== Hardware Design ===
+
|-
The hardware interface details of '''MOTOR Module''' with SJOne board are given below:
+
! scope="row"| 1.  
{|
+
| Signal wire connected to P2.5
|[[ File: RPM Sensor, DC and Servo Motor Hardware Design.jpeg|650px|thumb|left|RPM Sensor, DC and Servo Motor Hardware Interfacing]]
+
| GPIO that supplies pulses to controller
|
 
|[[ File: LCD.JPG |500px|thumb|right|LCD Hardware Connections]]
 
|
 
|}
 
 
 
=== Hardware Interface ===
 
 
 
====Electronic Speed Controller (ESC)====
 
We made use of the Traxxas ESC XL-05 which comes with the RC car. ESC stands for Electronic Speed Control. It is used to control the DC motor using PWM signals from the controller. It powers up when we connect a LiPo or NiMH battery of 7.4v. The ESC has a dc-to-dc converter which converts 7.4v to 6v and provides it to DC motor. It can provide high current to the power hungry DC motors running at faster speeds. It has an LED and a button which is used for calibration and setting different modes for the car.
 
 
[[File:CMPE243 F17 nano ESC.jpg|220px|thumb|right|Traxxas ESC XL5]]
 
{| class="wikitable"
 
|+ ESC Pin Connection
 
|-
 
! scope="col"| S.No
 
! scope="col"| Wires - ESC
 
! scope="col"| Description
 
|-
 
! scope="row"| 1.  
 
| Positive wire (already Connected)
 
| Connects to DC Motor positive
 
 
|-
 
|-
 
! scope="row"| 2.  
 
! scope="row"| 2.  
| Negative wire (already Connected)
+
| VCC
| Connects to DC Motor negative
+
| 6V power supply from ESC
 
|-
 
|-
 
! scope="row"| 3.  
 
! scope="row"| 3.  
| Positive Supply
+
| GND
| Connects to supply of Li-Po battery
+
| Common ground
 
|-
 
|-
! scope="row"| 4.
+
|}
| Ground Wire
+
<br>
| Connects to ground of Li-Po battery
+
 
|-
+
==== uLCD32-PTU ====
|-
+
 
! scope="row"| 5.  
+
uLCD32-PTU by 4D systems has a 3.2" TFT LCD Display module. The module comes with a display resolution of 240x320 pixels. 4D Systems provides a programming cable based on UART for burning the LCD code to the module. The project is burnt to a uSD card which is used for display during booting of the LCD. It is recommended that we use the programming adapter provided by 4D systems as it has a special reset button that can be used to download the built project to the LCD display.Once the LCD display was configured with different widgets and screens, the motor module was coded to display information in LCD through UART. Workshop4 IDE was used to program the GUI, and data was transmitted from the SJOne board through UART communication. The LCD displays the main menu screen with options of all the modules: Sensor, Motor, Bridge, GPS, Compass and MIA information.
| PWM input connected to P2.0
 
| PWM Signal From SJOne
 
|-
 
! scope="row"| 6.  
 
| Servo Vcc Supply
 
| 6V power supply to power the servo
 
|-
 
! scope="row"| 7.  
 
| Common Ground
 
| Negative terminal
 
|-
 
|}
 
  
====DC Motor====
+
These modules represent the page numbers of the display whose information can be found from the pre-processed data format of the LCD.This data format contains the following fields:
 +
*The write command
 +
*Type of the object
 +
*Object ID
 +
*MSB and LSB values to be displayed in the LED.
 +
*The last pair of hex value is for checksum.
  
[[File:CMPE_S19_techsavy_dc.jpg‎|350px|thumb|right|Traxxas DC Motor]]
+
The following figure shows the programming cable and the pins used for uLCD32-PTU.
The DC motor is controlled using the ESC which get PWM pulses for controlling it. A PWM signal wire is connected to the microcontroller and the required current is provided by the LiPo battery and the ESC.
+
[[File:CMPE243_F17_nano_LCD-connection.JPG|thumb|300px|LCD connections|right]]
 +
<br>
 
{| class="wikitable"
 
{| class="wikitable"
|+ DC Motor Pin Connection
+
|+ LCD Pin Connection
 
|-
 
|-
 
! scope="col"| S.No
 
! scope="col"| S.No
! scope="col"| Wires - DC Motor
+
! scope="col"| Wires - LCD interface
! scope="col"| Description
+
! scope="col"| Function
 
|-
 
|-
 
! scope="row"| 1.  
 
! scope="row"| 1.  
| Positive Wire (already Connected)
+
| TX
| Positive Terminal
+
| Data Transmission connected to UART RX of SJ1 board
 +
|-
 +
! scope="row"| 2.
 +
| RX
 +
| Data Reception connected to UART TX of SJ1 board
 
|-
 
|-
 
! scope="row"| 2.  
 
! scope="row"| 2.  
| Negative Wire (already Connected)
+
| VCC
| Negative terminal
+
| Input 5v supply
 +
|-
 +
! scope="row"| 3.
 +
| GND
 +
| Common ground
 +
|-
 +
! scope="row"| 4.
 +
| RES
 +
| Reset Pulse(Not Required for our project)
 
|-
 
|-
 
|}
 
|}
  
The DC motor is controlled using PWM at 100Hz.
+
=== 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.<br>
  
{| class="wikitable"
+
Pseudo code for initializing PWM to 100Hz. <br>
|+ DC MOTOR Configuration
+
PWM *motor_control;    //pointer object defined globally
|-
+
PWM *servo_control;
! Operation !! Pulse Width Range(ms) !! Duty-cycle(%)
+
void init_pwm(long unsigned int freq) {
|-
+
    motor_control = new PWM(PWM::pwm1, freq);     // using PWM constructor to initialize the PWM 2.0 pin to desired frequency
| FORWARD     || 1.51 - 2.00     || 15.1 - 20.0     
+
     servo_control = new PWM(PWM::pwm2, freq);
|-
+
}
| STOP      || 1.50    || 15.0
 
|-
 
| REVERSE     || 1.00 - 1.49    || 10.0 - 14.9
 
|}
 
  
 +
====DC Motor====
 +
The DC motor is connected to pin P2.0 on SJONE board. The DC motor is commanded every 100ms to change or maintain its speed or direction(FORWARD, REVERSE and STOP). A switch case is used to check the command that we are receiving over CAN bus from master.
  
'''NOTE''': Before using the Traxxas ESC to give PWM signal to DC motor calibrate it by going to this website:<br>
+
Pseudo code for dc motor and speed control
:https://traxxas.com/support/Programming-Your-Traxxas-Electronic-Speed-Control<br>
+
float speed = get_speed();
 +
float _error = calculate_error_PID(drive_forward->MOTOR_mps, speed, &dc_motor);
 +
*PWM_percent += _error
 +
set_pwm_value(motor_1, *PWM_percent);
  
:The ESC must be given a pulse of 1.5ms when we turn it on or else the DC motor won't respond to PWM pulses.<br>
+
====Servo Motor====
:Step 1: Give 2.00ms on-time pulses when LED blinks red once.<br>
+
The Servo motor is connected to pin P2.1 on SJONE board. The servo motor is commanded every 10ms to change or maintain its angle between 0 and 180 degrees. We receive angle in the range of -90(full left), 0(neutral) and +90(full right) from master. The calculate PWM_duty_cycle_servo function maps the angle received from master to PWM signal and rotates the servo motor accordingly.
:Step 2: Give 1.50ms on-time pulses when LED blinks red twice.<br>
+
 
:Step 3: Give 1.00ms on-time pulses and the LED color changes from red to green showing that the calibration was successful.<br>
+
Pseudo code for servo motor and angle calculation
 +
on_time = 10 + ((servo->MOTOR_STEER_cmd + 90) * (10/180));
 +
set_pwm_value(servo_2, on_time);
  
====Servo Motor====
+
====RPM Sensor====
[[File:CMPE243_F17_nano_servo.jpg ‎|200px|thumb|right|Traxxas Servo Motor]]
+
The RPM sensor is connected to pin P2.6 of SJONE board. When the wheel rotates once we get one pulse. We make use of interrupt to register these pulses in a 400ms time frame and then calculate the speed in m/s based on the formula:
The direction the vehicle's front wheels turn is dependent on the servo motor in the vehicle. Based on various PWM signals, the servo steers the front wheels of the vehicle in the left and right direction. The servo has 3 wires of which one is for the PWM input signal whereas the other two are to power up the servo. We powered our servo motor using the 6v power supply from the battery elimination circuit present in the ESC so that a single switch to turn on and off both the servo and DC motor. PWM signals to control the servo is provided by the motor controller. Based on the PWM signal from the SJOne board, the
+
speed_m_per_sec = (circumference * rotation_per_sec) / (constant);
shaft shall be rotated to a certain degree left or right
+
After every 400ms we reset the pulse counter. We have an ISR which increments these pulses.
 +
void eint3_handler(void){
 +
    pulse++;
 +
}
  
{| class="wikitable"
+
====LED Blinking signals for MOTOR CONTROLLER====
|+ Servo Motor Pin Connection
+
*RED LED ON: MASTER HEARTBEAT STATUS on CAR
|-
+
*BLUE LED ON: Car is moving in reverse direction
! scope="col"| S.No
+
*YELLOW LED ON: Car is stopped
! scope="col"| Wires - Servo Motor
+
*GREEN LED ON: Car is moving in forward direction
! scope="col"| Function
 
|-
 
! scope="row"| 1.
 
| PWM connected to P2.1
 
| PWM signal from SJOne board
 
|-
 
! scope="row"| 2.
 
| VCC
 
| 6V power supply from ESC
 
|-
 
! scope="row"| 3.
 
| Ground
 
| Common ground to system
 
|-
 
|}
 
  
====RPM Sensor====
+
====LCD Software Flow Chart====
[[File:CMPE243_F17_nano_Speed_Sensor.jpg ‎|250px|thumb|right|Traxxas Speed Sensor]]
+
[[File:CMPE_243_TechSavy_LCD_Refresh.JPG|450px|thumb|center|LCD Software Flowchart: 1Hz Task]]
RPM sensor is used as a feedback element in the PID to maintain a constant speed of the vehicle. The RPM sensor mounts on the rear DC motor shaft compartment with a special assembly also provided by Traxxas. We make use of one magnet and we get one pulse on one wheel rotation The sensor works on the hall effect principle where it provides a current across its terminal when placed in a magnet's field. These pulses are read by the SJOne board and fed to the speed control algorithm. The RPM sensor has 3 wires, the white where are the output wire that provides the pulses to the SJone board and the other wires power the sensor.
 
  
=====Implementation=====
+
====Programming SJONE Board for LCD Display====
1. The idea is that every time the motor completes 1 whole revolution, it reaches very close to the sensor. And when the sensor detects the magnet nearby, it sends out a high pulse until the magnet moves away from it. Therefore, upon detecting the X number of a rising edge in Y seconds we can say that rpm was X revolutions/Y seconds.<br>
+
*As raw data often cannot be displayed on the LCD directly, the values to be displayed had to be converted to appropriate byte-sized values.
2. During our initial testing of RPM Sensor with SJOne board, we saw that regardless of whether we bring the magnet close to the sensor or not, the signal voltage was always high. After some trail and errors, we found out that the signal pin(white wire) had to be connected to the VCC(red wire) across a 1K resistor which can act as weak pull down when it detects the magnet.<br>
+
*Communication with SJOne board was established at the baud rate of 115200 bps.
 +
*Commands for writing data and reading acknowledgment for various gauges were coded in the SJ1 board.
  
{| class="wikitable"
+
====Creating a project using Workshop 4 IDE and programming the LCD display====
|+ Speed Sensor Pin Connection
+
* After finalizing the design of the LCD's layout, a genie project was created using Workshop 4.
|-
+
* The layout was split into different forms (pages) and appropriate buttons and gauges were added for display.
! scope="col"| S.No
+
* uLCD-32PTU was programmed with the help of programming cable provided by 4D systems.
! scope="col"| Wires - RPM Sensor
 
! scope="col"| Function
 
|-
 
! scope="row"| 1.
 
| Signal wire connected to P2.5
 
| GPIO that supplies pulses to controller
 
|-
 
! scope="row"| 2.  
 
| VCC
 
| 6V power supply from ESC
 
|-
 
! scope="row"| 3.  
 
| GND
 
| Common ground
 
|-
 
|}
 
<br>
 
  
==== uLCD32-PTU ====
+
The steps taken for interfacing the LCD display with the SJONE board is shown on the right:
  
uLCD32-PTU by 4D systems has a 3.2" TFT LCD Display module. The module comes with a display resolution of 240x320 pixels. 4D Systems provides a programming cable based on UART for burning the LCD code to the module. The project is burnt to a uSD card which is used for display during booting of the LCD. It is recommended that we use the programming adapter provided by 4D systems as it has a special reset button that can be used to download the built project to the LCD display.Once the LCD display was configured with different widgets and screens, the motor module was coded to display information in LCD through UART. Workshop4 IDE was used to program the GUI, and data was transmitted from the SJOne board through UART communication. The LCD displays the main menu screen with options of all the modules: Sensor, Motor, Bridge, GPS, Compass and MIA information.
+
Each of the reading is considered as a object with the object type ID and object number. Below are the list of objects used for lcd.
 +
#define GPS_DEST_LATITUDE_OBJ        0
 +
#define GPS_DEST_LONGITUDE_OBJ      1
 +
#define GPS_CURRENT_LATITUDE_OBJ    2
 +
#define GPS_CURRENT_LONGITUDE_OBJ    3
 +
#define GPS_HEADING_OBJ              13
 +
#define GPS_BEARING_OBJ              14
 +
#define GPS_DISTANCE_OBJ            3
 +
#define MOTOR_SPEED_MS_OBJ          8
 +
#define MOTOR_PWM_OBJ                12
 +
#define MOTOR_RPM_OBJ                4
 +
#define MOTOR_TURNING_ANGLE_OBJ      9
 +
#define MOTOR_DISTANCE_COVERED_OBJ  10
 +
#define MOTOR_DISTANCE_LEFT_OBJ      11
  
These modules represent the page numbers of the display whose information can be found from the pre-processed data format of the LCD.This data format contains the following fields:
+
So our approach was to send a LCDquery at 1Hz task using the below function.
*The write command
+
void lcd_screen_query(void)
*Type of the object
+
{
*Object ID
+
    char comm[] = {0, 0x0a, 0, 0x0a};
*MSB and LSB values to be displayed in the LED.
+
    for (int i = 0; i < (int)sizeof(comm); i++)
*The last pair of hex value is for checksum.
+
    {
 +
        uart3_put_char(comm[i], 0);
 +
    }
 +
}
  
The following figure shows the programming cable and the pins used for uLCD32-PTU.
+
This query sends a a array of character to LCD and LCD acknowledges it and sends the pre-formated data to the controller using lcd_receive() called at every 10Hz. The receive() will contain the page number(lcd_screen) based on the screen it is currently into and prints the data corresponding to that screen i.e. GPS screen will call GPS_print function to print the GPS values.
[[File:CMPE243_F17_nano_LCD-connection.JPG|thumb|300px|LCD connections|right]]
+
 
<br>
+
void lcd_print()
{| class="wikitable"
+
{
|+ LCD Pin Connection
+
    switch (lcd_screen)
|-
+
    {
! scope="col"| S.No
+
        case menu:
! scope="col"| Wires - LCD interface
+
            lcd_print_menu_screen();
! scope="col"| Function
+
            break;
|-
+
        case bridge:
! scope="row"| 1.
+
            lcd_print_bridge_screen();
| TX
+
            break;
| Data Transmission connected to UART RX of SJ1 board
+
        case gps:
|-
+
            lcd_print_gps_screen();
! scope="row"| 2.  
+
            break;
| RX
+
        case sensor:
| Data Reception connected to UART TX of SJ1 board
+
            lcd_print_sensor_screen();
|-
+
            break;
! scope="row"| 2.  
+
        case motor:
| VCC
+
            lcd_print_motor_screen();
| Input 5v supply
+
            break;
|-
+
        case home:
! scope="row"| 3.  
+
            lcd_print_home_screen();
| GND
+
            break;
| Common ground
+
        case mia:
|-
+
            lcd_print_mia_screen();
! scope="row"| 4.  
+
            break;
| RES
+
        case compass:
| Reset Pulse(Not Required for our project)
+
            lcd_print_compass_screen();
|-
+
            break;
 +
        default:
 +
            break;
 +
    }
 +
}
 +
 
 +
=='''LCD Screens'''==
 +
{|
 +
|[[File:screen8.PNG|thumb|220px|left|Main Screen]]
 +
|[[File:screen1.PNG|thumb|220px|none|Module Selection Screen]]
 +
|[[File:screen5.PNG|thumb|220px|right|MOTOR Screen]]
 +
|[[File:screen4.PNG|thumb|220px|none|Sensors Screen]]
 
|}
 
|}
  
=== Software Design ===
+
<br>
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.<br>
 
  
Pseudo code for initializing PWM to 100Hz. <br>
+
{|
PWM *motor_control;    //pointer object defined globally
+
|[[File:screen6.PNG|thumb|220px|left|MID Status Screen]]
PWM *servo_control;
+
|[[File:screen7.PNG|thumb|220px|none|GPS Screen]]
void init_pwm(long unsigned int freq) {
+
|[[File:screen3.PNG|thumb|220px|right|Compass Screen]]
    motor_control = new PWM(PWM::pwm1, freq);      // using PWM constructor to initialize the PWM 2.0 pin to desired frequency
+
|[[File:screen2.PNG|thumb|220px|none|Bluetooth Screen]]
    servo_control = new PWM(PWM::pwm2, freq);
+
|}
}
+
 
 +
<br>
  
====DC Motor====
+
==Flow charts==
The DC motor is connected to pin P2.0 on SJONE board. The DC motor is commanded every 100ms to change or maintain its speed or direction(FORWARD, REVERSE and STOP). A switch case is used to check the command that we are receiving over CAN bus from master.
+
{|
 +
|[[ File: DC_motor_control.jpg|500px|frameless|right]]
 +
|
 +
|[[ File: Servo_motor_control.jpeg|300px|frameless|center]]
 +
|
 +
|[[ File: Speed_calc.jpg|270px|frameless|left]]
 +
|}
 +
<br>
  
Pseudo code for dc motor and speed control
 
float speed = get_speed();
 
float _error = calculate_error_PID(drive_forward->MOTOR_mps, speed, &dc_motor);
 
*PWM_percent += _error
 
set_pwm_value(motor_1, *PWM_percent);
 
  
====Servo Motor====
+
<div align="center">'''DC motor speed and direction control using RPM sensor, Servo motor control and Speed calculator flow-chart'''</div>
The Servo motor is connected to pin P2.1 on SJONE board. The servo motor is commanded every 10ms to change or maintain its angle between 0 and 180 degrees. We receive angle in the range of -90(full left), 0(neutral) and +90(full right) from master. The calculate PWM_duty_cycle_servo function maps the angle received from master to PWM signal and rotates the servo motor accordingly.
 
  
Pseudo code for servo motor and angle calculation
+
=== Technical Challenges ===
on_time = 10 + ((servo->MOTOR_STEER_cmd + 90) * (10/180));
 
set_pwm_value(servo_2, on_time);
 
  
====RPM Sensor====
+
'''PWM frequency setting problem'''<br>
The RPM sensor is connected to pin P2.6 of SJONE board. When the wheel rotates once we get one pulse. We make use of interrupt to register these pulses in a 400ms time frame and then calculate the speed in m/s based on the formula:
+
:The PWM frequency won't set if we were making use of global objects directly using the SJONE PWM drivers. We verified using logic analyzer that our frequency was getting set to 1.19KHz instead of 100Hz.<br>
  speed_m_per_sec = (circumference * rotation_per_sec) / (constant);
+
  PWM motor_control(PWM::pwm1, freq);
After every 400ms we reset the pulse counter. We have an ISR which increments these pulses.
+
PWM servo_control(PWM::pwm2, freq);
  void eint3_handler(void){
+
:'''Solution:''' After trying out many things we made use of global pointer objects to solve the problem.<br>
     pulse++;
+
PWM *motor_control;    //pointer object defined globally
  }
+
PWM *servo_control;
 +
  void init_pwm(long unsigned int freq) {
 +
     motor_control = new PWM(PWM::pwm1, freq);      // using PWM constructor to initialize the PWM 2.0 pin to desired frequency
 +
    servo_control = new PWM(PWM::pwm2, freq);
 +
  }  
  
====LED Blinking signals for MOTOR CONTROLLER====
+
'''DC motor shooting randomly'''<br>
*RED LED ON: MASTER HEARTBEAT STATUS on CAR
+
: When we were testing our DC motor, we found that our dc motor would shoot randomly in forward and reverse direction when using GPP board. We checked our code and the entire wiring but were not able to fix it.<br>
*BLUE LED ON: Car is moving in reverse direction
+
:'''Solution:''' When our PCB arrived we tested the DC motor on it and it worked fine. One suggestion would be to use the PCB as soon as possible as it won't waste your time on debugging unnecessary problems.
*YELLOW LED ON: Car is stopped
 
*GREEN LED ON: Car is moving in forward direction
 
  
====LCD Software Flow Chart====
+
'''PID Calibration for uphill and downhill'''<br>
[[File:CMPE_243_TechSavy_LCD_Refresh.JPG|450px|thumb|center|LCD Software Flowchart: 1Hz Task]]
+
: It uses an extensive amount of time to get the PID loop working which gives proper error values which maneuvers the car without stopping on uphill and controls speed during the downhill.
 +
: '''Solution:'''You should start using PID for maneuvering uphill and downhill conditions from the beginning.
  
====Programming SJONE Board for LCD Display====
+
'''LCD Refreshing'''<br>
*As raw data often cannot be displayed on the LCD directly, the values to be displayed had to be converted to appropriate byte-sized values.
+
: During testing the data received in LCD, we noticed that LCD was not getting refreshed quickly i.e even though PCAN dongle was updating data quickly but LCD was showing the data after a few seconds. At one point, the LCD stopped updating data.
*Communication with SJOne board was established at the baud rate of 115200 bps.
+
: '''Solution:'''We used snprintf() for GPS and Sensor values.For Compass and Motor, we implemented MSB and LSB approach where lower 8 bits of data(int) was stored in LSB and upper 8 bits in MSB, followed by our custom display function lcd_put_comm() which converted the data to the pre-formatted data and displayed data over UART using uart_put_char(). Below is an example
*Commands for writing data and reading acknowledgment for various gauges were coded in the SJ1 board.
+
    char msb,lsb = 0;
 +
    int local_heading = gps_bearing * 100;
 +
    lsb = (char)((char) local_heading & 0xff);
 +
    msb = (char)((char) (local_heading >> 8) & 0xff);
 +
    lcd_put_comm(WRITE_OBJ, LED_DIGITS, GPS_HEADING_OBJ, msb, lsb);
  
====Creating a project using Workshop 4 IDE and programming the LCD display====
+
<BR/>
* After finalizing the design of the LCD's layout, a genie project was created using Workshop 4.
 
* The layout was split into different forms (pages) and appropriate buttons and gauges were added for display.
 
* uLCD-32PTU was programmed with the help of programming cable provided by 4D systems.
 
  
The steps taken for interfacing the LCD display with the SJONE board is shown on the right:
+
=='''Geographical Controller'''==
  
Each of the reading is considered as a object with the object type ID and object number. Below are the list of objects used for lcd.
+
Geographical Controller is one the most important controller in the autonomous car which helps it to navigate to its destination. This modules continuously update the position and orientation of the car with respect to geographical north and send the data to Master, Motor and Android controller boards. We are using the Adafruit Ultimate GPS module and CMPS11.
#define GPS_DEST_LATITUDE_OBJ        0
 
#define GPS_DEST_LONGITUDE_OBJ      1
 
#define GPS_CURRENT_LATITUDE_OBJ    2
 
#define GPS_CURRENT_LONGITUDE_OBJ    3
 
#define GPS_HEADING_OBJ              13
 
#define GPS_BEARING_OBJ              14
 
#define GPS_DISTANCE_OBJ            3
 
#define MOTOR_SPEED_MS_OBJ          8
 
#define MOTOR_PWM_OBJ                12
 
#define MOTOR_RPM_OBJ                4
 
#define MOTOR_TURNING_ANGLE_OBJ      9
 
#define MOTOR_DISTANCE_COVERED_OBJ  10
 
#define MOTOR_DISTANCE_LEFT_OBJ      11
 
  
So our approach was to send a LCDquery at 1Hz task using the below function.
+
* GEO CONTROLLER Git Link: <font color="blue"><U>[https://gitlab.com/tech-savycmpe243/cmpe243_techsavy_rc_car/tree/master/Geographical_Controller_Module]</U></font>
void lcd_screen_query(void)
 
{
 
    char comm[] = {0, 0x0a, 0, 0x0a};
 
    for (int i = 0; i < (int)sizeof(comm); i++)
 
    {
 
        uart3_put_char(comm[i], 0);
 
    }
 
}
 
  
This query sends a a array of character to LCD and LCD acknowledges it and sends the pre-formated data to the controller using lcd_receive() called at every 10Hz. The receive() will contain the page number(lcd_screen) based on the screen it is currently into and prints the data corresponding to that screen i.e. GPS screen will call GPS_print function to print the GPS values.
+
=== Hardware Design ===
 +
 +
The hardware interface details of '''GPS and Compass Module''' with SJOne board are given below:
 +
 
 +
[[ File: CmpE243_TechSavy_GEO_Controller.jpg|679px|thumb|centre||GPS & CMPS11 Module Hardware Interfacing]]
 +
 
 +
<br>
 +
 
 +
* '''LED Blinking signals for GEO CONTROLLER ON CAR'''
 +
* RED LED ON: MASTER HEARTBEAT STATUS on CAR
 +
* BLUE LED ON: Shows GPS FIX STATUS on CAR
 +
* GREEN LED ON: COMPASS Data Indication
 +
 
 +
'''GPS'''
  
void lcd_print()
+
* '''GPS PinOut'''
  {
+
  * VCC: 3.3V Power
    switch (lcd_screen)
+
* GND: Ground
    {
+
* TXD: Serial Transmit pin connected to RXD2 of SJOne board
        case menu:
+
* RXD: Serial Receive  pin connected to TXD2 of SJOne board
            lcd_print_menu_screen();
+
* FIX: States if GPS is fixed not
            break;
 
        case bridge:
 
            lcd_print_bridge_screen();
 
            break;
 
        case gps:
 
            lcd_print_gps_screen();
 
            break;
 
        case sensor:
 
            lcd_print_sensor_screen();
 
            break;
 
        case motor:
 
            lcd_print_motor_screen();
 
            break;
 
        case home:
 
            lcd_print_home_screen();
 
            break;
 
        case mia:
 
            lcd_print_mia_screen();
 
            break;
 
        case compass:
 
            lcd_print_compass_screen();
 
            break;
 
        default:
 
            break;
 
    }
 
}
 
  
=='''LCD Screens'''==
+
[[ File: Gps Dump.png|700px|thumb|centre|| GPRMC NMEA DATA]]
{|
 
|[[File:screen8.PNG|thumb|220px|left|Main Screen]]
 
|[[File:screen1.PNG|thumb|220px|none|Module Selection Screen]]
 
|[[File:screen5.PNG|thumb|220px|right|MOTOR Screen]]
 
|[[File:screen4.PNG|thumb|220px|none|Sensors Screen]]
 
|}
 
  
 
<br>
 
<br>
  
{|
+
GPS is a global navigation satellite system that provides geolocation and time information to a GPS receiver anywhere on or near the Earth where there is an unobstructed line of sight to four or more GPS satellites.
|[[File:screen6.PNG|thumb|220px|left|MID Status Screen]]
 
|[[File:screen7.PNG|thumb|220px|none|GPS Screen]]
 
|[[File:screen3.PNG|thumb|220px|right|Compass Screen]]
 
|[[File:screen2.PNG|thumb|220px|none|Bluetooth Screen]]
 
|}
 
  
<br>
+
The GPS module used in this project runs on UART communication protocol. Its default baud rate is 9600bps and we are working on the same baud rate to extract GPS data. The GPS module works on NMEA 0183 standards which define the electrical and data specification for communication between the GPS module and its controller. We are using the Recommended minimum specific GPS/Transit data (GPRMC) command. It provides us with three important data which are Fix, Latitude, and Longitude, required for localization and navigation of the car. The update rate of these data from the GPS module is configured at 10Hz and 5Hz for fix control status.
  
==Flow charts==
+
* GPS Configurations:
{|
 
|[[ File: DC_motor_control.jpg|500px|frameless|right]]
 
|
 
|[[ File: Servo_motor_control.jpeg|300px|frameless|center]]
 
|
 
|[[ File: Speed_calc.jpg|270px|frameless|left]]
 
|}
 
<br>
 
  
 +
GPS configuration Settings that we have used for the Adafruit GPS module is shown in the following picture. As per Arduino data-sheet, we can use different commands setting to set the different update rate from once a second (1 Hz) to 10 times a second (10 Hz) as per user requirements.
  
<div align="center">'''DC motor speed and direction control using RPM sensor, Servo motor control and Speed calculator flow-chart'''</div>
+
[[ File: CMPE243_TechSavy_GPS_Config.JPG|600px|thumb|center|| GPS Configuration Settings]]
  
=== Technical Challenges ===
+
'''Compass'''
  
'''PWM frequency setting problem'''<br>
+
* '''Compass PinOut'''  
:The PWM frequency won't set if we were making use of global objects directly using the SJONE PWM drivers. We verified using logic analyzer that our frequency was getting set to 1.19KHz instead of 100Hz.<br>
+
* VCC: 3.3V Power
  PWM motor_control(PWM::pwm1, freq);
+
  * GND: Ground
  PWM servo_control(PWM::pwm2, freq);
+
  * SCL: Serial Clock pin connected to SCL of SJOne board
:'''Solution:''' After trying out many things we made use of global pointer objects to solve the problem.<br>
+
  * SDA: Serial DATA pin connected to SDA of SJOne board
  PWM *motor_control;    //pointer object defined globally
 
PWM *servo_control;
 
void init_pwm(long unsigned int freq) {
 
    motor_control = new PWM(PWM::pwm1, freq);      // using PWM constructor to initialize the PWM 2.0 pin to desired frequency
 
    servo_control = new PWM(PWM::pwm2, freq);
 
}
 
  
'''DC motor shooting randomly'''<br>
+
A Compass is an instrument used for navigation and orientation that shows direction relative to the geographic cardinal directions (or points). Compass is communicating over I2C with SJ One board. The register 2 and 3 of the compass provide the compass bearing angle (0- 360 range). Calibrating the compass is an important part. We are calibrating it on ‘horizontal calibration mode’, it works for us because the compass has tilt calibration.
: When we were testing our DC motor, we found that our dc motor would shoot randomly in forward and reverse direction when using GPP board. We checked our code and the entire wiring but were not able to fix it.<br>
 
:'''Solution:''' When our PCB arrived we tested the DC motor on it and it worked fine. One suggestion would be to use the PCB as soon as possible as it won't waste your time on debugging unnecessary problems.
 
  
'''PID Calibration for uphill and downhill'''<br>
+
We are using the compass in I2C mode of operation. The following table on the left shows the registers and their functions and the software flow chart for getting/setting compass data and calibration on demand and We are using the Compass bearing (16-bit) given by the compass registers 2 and 3 to calculate our car heading.
: It uses an extensive amount of time to get the PID loop working which gives proper error values which maneuvers the car without stopping on uphill and controls speed during the downhill.
+
<br>
: '''Solution:'''You should start using PID for maneuvering uphill and downhill conditions from the beginning.
 
  
'''LCD Refreshing'''<br>
+
{|
: During testing the data received in LCD, we noticed that LCD was not getting refreshed quickly i.e even though PCAN dongle was updating data quickly but LCD was showing the data after few seconds. At one point, the LCD stopped updating data.
+
|[[File:CmpE243_I2c_compass_registers.png|thumb|500px|left|thumb|Registers of CMPS11]]
: '''Solution:'''We used snprintf() for GPS and Sensor values.For Compass and Motor, we implemented MSB and LSB approach where lower 8 bits of data(int) was stored in LSB and upper 8 bits in MSB, followed by our custom display function lcd_put_comm() which converted the data to the pre-formatted data and displayed data over UART using uart_put_char(). Below is an example
+
|[[File:CMPE_243_TechSavy_Compass_Calibration.jpg|thumb|450px|Right|thumb|Registers of CMPS11]]
    char msb,lsb = 0;
+
|}
    int local_heading = gps_bearing * 100;
+
<br>
    lsb = (char)((char) local_heading & 0xff);
 
    msb = (char)((char) (local_heading >> 8) & 0xff);
 
    lcd_put_comm(WRITE_OBJ, LED_DIGITS, GPS_HEADING_OBJ, msb, lsb);
 
  
 +
===Software Design & Implementation===
  
<HR>
+
The Geographical Controller is in place for navigation purpose. It has two essential parts, namely GPS and compass. It provides direction to the car, by calculating the heading angle and the distance between the coordinates, based on GPS and compass readings. To calculate the heading angle, we need a compass bearing angle and angle between the line joining the two coordinates and the true north(bearing angle for GPS).
<BR/>
 
  
=='''Geographical Controller'''==
+
<br>
  
Geographical Controller is one the most important controller in the autonomous car which helps it to navigate to its destination. This modules continuously update the position and orientation of the car with respect to geographical north and send the data to Master, Motor and Android controller boards. We are using the Adafruit Ultimate GPS module and CMPS11.
+
[[ File: Power_On_SMFC.JPG|600px|thumb|center||Hard Power ON Flow Chart]]
  
* GEO CONTROLLER Git Link: <font color="blue"><U>[https://gitlab.com/tech-savycmpe243/cmpe243_techsavy_rc_car/tree/master/Geographical_Controller_Module]</U></font>
+
<br>
  
=== Hardware Design ===
+
[[ File: Periodic_task_SMFC.JPG|500px|thumb|right|| SFMC for 1HZ]]
+
[[ File: Periodic_task_10Hz_SMFC.JPG|600px|thumb|centre|| SFMC for 10Hz]]
The hardware interface details of '''GPS and Compass Module''' with SJOne board are given below:
 
 
 
[[ File: CmpE243_TechSavy_GEO_Controller.jpg|679px|thumb|centre||GPS & CMPS11 Module Hardware Interfacing]]
 
  
 
<br>
 
<br>
  
* '''LED Blinking signals for GEO CONTROLLER ON CAR'''
+
==== Distance between the two coordinates calculation ====
* RED LED ON: MASTER HEARTBEAT STATUS on CAR
 
* BLUE LED ON: Shows GPS FIX STATUS on CAR
 
* GREEN LED ON: COMPASS Data Indication
 
  
'''GPS'''
+
The distance between the two coordinates can be calculated using the Haversine formula.
  
* '''GPS PinOut'''
+
  a = sin²(Δφ/2) + cos φ1 ⋅ cos φ2 ⋅ sin²(Δλ/2)
* VCC: 3.3V Power
+
  c = 2 ⋅ atan2(√a, √(1−a))
* GND: Ground
+
  d = R ⋅ c
* TXD: Serial Transmit pin connected to RXD2 of SJOne board
+
  where,
* RXD: Serial Receive  pin connected to TXD2 of SJOne board
+
        φ1 = Latitude of 1st Coordinate
  * FIX: States if GPS is fixed not
+
        φ2 = Latitude of 2nd Coordinate
 
+
        λ1 = Longitude of 1st Coordinate
[[ File: Gps Dump.png|700px|thumb|centre|| GPRMC NMEA DATA]]
+
        λ2 = Longitude of 2nd Coordinate
 +
        Δφ = φ2 - φ1
 +
        Δλ = λ2 - λ1
 +
        d = distance between the two coordinates
 +
        R  = earth’s radius (mean radius = 6,371km)
 +
  Note: All the angles should be in radians.
  
<br>
+
==== GPS Heading angle calculation ====
  
GPS is a global navigation satellite system that provides geolocation and time information to a GPS receiver anywhere on or near the Earth where there is an unobstructed line of sight to four or more GPS satellites.
+
[[File:Bearing Angle.JPG|500px|thumb|center|Bearing angle calculation ]]
  
The GPS module used in this project runs on UART communication protocol. Its default baud rate is 9600bps and we are working on the same baud rate to extract GPS data. The GPS module works on NMEA 0183 standards which define the electrical and data specification for communication between the GPS module and its controller. We are using the Recommended minimum specific GPS/Transit data (GPRMC) command. It provides us with three important data which are Fix, Latitude, and Longitude, required for localization and navigation of the car. The update rate of these data from the GPS module is configured at 10Hz and 5Hz for fix control status.
+
With reference to the figure, the Heading angle for GPS is the angle between the line joining the two coordinates and the true north. To calculate it graphically, draw a vector pointing towards the destination coordinates from the start point coordinate and measure the angle between the vector and the true north. Use the below formula to calculate the angle mathematically.
  
* GPS Configurations:
+
  Heading angle(α) = atan2(sin Δλ ⋅ cos φ2 , cos φ1 ⋅ sin φ2 − sin φ1 ⋅ cos φ2 ⋅ cos Δλ)
 +
  where,
 +
        φ1 = Latitude of 1st Coordinate
 +
        φ2 = Latitude of 2nd Coordinate
 +
        λ1 = Longitude of 1st Coordinate
 +
        λ2 = Longitude of 2nd Coordinate
 +
        Δλ = λ2 - λ1
  
GPS configuration Settings that we have used for the Adafruit GPS module is shown in the following picture. As per Arduino data-sheet, we can use different commands setting to set the different update rate from once a second (1 Hz) to 10 times a second (10 Hz) as per user requirements.
+
==== GPS Checkpoint Navigation ====
 +
The car reads the value of current coordinates from the GPS module to determine its Euclidean distance from the first checkpoint. It also checks the value on the compass to know which direction it should preferably move in i.e. Heading angle. The sensor readings help it ascertain that there isn't an obstacle to hinder its movement in the determined direction.
  
[[ File: CMPE243_TechSavy_GPS_Config.JPG|600px|thumb|center|| GPS Configuration Settings]]
+
We have selected 23 checkpoints on the location where the demo is going to takes place and we have filled these coordinates in a Checkpoint Array as shown below.
  
'''Compass'''
+
{|
 +
|[[File:Checkpoints.JPG|thumb|400px|left|thumb|Selected Checkpoints]]
 +
|[[File:CheckPointsArray.JPG|thumb|350px|Right|thumb|Checkpoints Array]]
 +
|}
  
* '''Compass PinOut'''
+
<br>
* VCC: 3.3V Power
 
* GND: Ground
 
* SCL: Serial Clock pin connected to SCL of SJOne board
 
* SDA: Serial DATA pin connected to SDA of SJOne board
 
  
A Compass is an instrument used for navigation and orientation that shows direction relative to the geographic cardinal directions (or points). Compass is communicating over I2C with SJ One board. The register 2 and 3 of the compass provide the compass bearing angle (0- 360 range). Calibrating the compass is an important part. We are calibrating it on ‘horizontal calibration mode’, it works for us because the compass has tilt calibration.
+
* The Car begins navigating its way from its current location to the final destination using enlisted checkpoints. When the car arrives at a first checkpoint, then GEO Controller will look into its GPS checkpoints constant array to look for next nearest checkpoint.  
 +
* While selecting Checkpoint we are using Linear Searching technique to select next checkpoint which is closer to the current location and as well as closer to the final destination.
  
We are using the compass in I2C mode of operation. The following table on the left shows the registers and their functions and the software flow chart for getting/setting compass data and calibration on demand and We are using the Compass bearing (16-bit) given by the compass registers 2 and 3 to calculate our car heading.
+
The Software state machine flow chart for GPS Navigation is shown below:
<br>
+
[[File:Cmpe243_TechSavy_GPS_Navigation.JPG|600px|thumb|centre|GPS Checkpoint Navigation]]
  
{|
+
==== Technical Challenges ====
|[[File:CmpE243_I2c_compass_registers.png|thumb|500px|left|thumb|Registers of CMPS11]]
 
|[[File:CMPE_243_TechSavy_Compass_Calibration.jpg|thumb|450px|Right|thumb|Registers of CMPS11]]
 
|}
 
<br>
 
  
===Software Design & Implementation===
+
* '''Issues 1''' - GPS doesn’t retain configuration settings; GPS module was forgetting its baud setting of 57600bps configuration settings after a long run testing of GPS module(we kept GPS for overnight testing to capture logs of GPRMC to check its location consistency) before the implementation of Distance calculation so after 4-5 hours its start giving Null values for latitude and longitude after reviewing the logs of the data captured that was giving garbage data as UART baud mismatching gives then it has to be configured again that means baud rate setting using PMTK command.
  
The Geographical Controller is in place for navigation purpose. It has two essential parts, namely GPS and compass. It provides direction to the car, by calculating the heading angle and the distance between the coordinates, based on GPS and compass readings. To calculate the heading angle, we need a compass bearing angle and angle between the line joining the two coordinates and the true north(bearing angle for GPS).  
+
  '''Solution''' - As per recommendation is given in Arduino Data sheet we should use default baud settings of 9600 later we never faced this issue and it was giving a good fix.
  
<br>
+
*'''Issue 2''' - One of the most important thing with GPS is to get a quick fix. Our First Time to fix was coming approx 50seconds even in the open sky which is not good for self-driving car the moment engine of the car turns on we should have Coordinates of the car to navigate this to the destination location. So first Time to fix was one the hurdle for us.
  
[[ File: Power_On_SMFC.JPG|600px|thumb|center||Hard Power ON Flow Chart]]
+
  '''Solution''' - We have followed one of the Arduino Forum in which one of the experts give few tips on how to improve this GPS Fix issue and one of the tips worked for us was the of the Cell battery with the voltage of more than 2.89v. This resolves GPS fix the issue for us.
 +
 
 +
*'''Issue 3''' - Compass frequently losing its calibration when we were using CMPS11 in calibrated Mode.
 +
  '''Solution''' - Using CMPS11 in default calibration mode helped us to get rid of this problem
 +
 
 +
*'''Issue 4''' Ahhhh!! Faced task overrun issue with GPS NMEA data. When we were using NMEA parsing and shortest path algorithm in one task or even in two different tasks code was crashing like anything. However, NMEA parsing and Path Finding algorithm were working fine.
 +
  '''Solution''' - Preet's easy parsing function(using sscanf) and his advice of using separate task using FreeRTOS helped us resolving this problem.
 +
 
 +
*'''Issue 5''' During parsing of GPS Coordinates we have faced one issue with data type Float. Due to can transmission, we were using float data type for Latitude and longitude and what we have noticed that after getting data in string/char* and converting it to float then last two-three decimal places of latitude and longitude were changing frequently due to which Calculated distance from SOurce to destination was changing randomly even car is sitting at one location.
  
<br>
+
  '''Solution''' - GPS coordinates require double datatype so, we took coordinates as double and then while sending data on CAN we were typecasting that to float. As we were doing all calculation related to coordinates, distance and checkpoints calculations on GEO Controller itself. So after doing all the calculations in double, we were type casting data to float and we were sending that to MASTER & BRIDGE.
  
[[ File: Periodic_task_SMFC.JPG|500px|thumb|right|| SFMC for 1HZ]]
 
[[ File: Periodic_task_10Hz_SMFC.JPG|600px|thumb|centre|| SFMC for 10Hz]]
 
  
<br>
+
<BR/>
  
==== Distance between the two coordinates calculation ====
+
=='''Bridge Controller Communication'''==
 +
Bridge Controller is used for communication between the SJOne board and the android phone using the HC-05 Bluetooth module. The main purpose of the bridge Controller is to receive the start/stop command and destination location from the Android app. Bridge controller will transmit all the sensor information and debug information and this information will be displayed on the android app.
  
The distance between the two coordinates can be calculated using the Haversine formula.
+
* BRIDGE CONTROLLER Git Link: <font color="blue"><U>[https://gitlab.com/tech-savycmpe243/cmpe243_techsavy_rc_car/tree/master/Bridge_Controller_Module]</U></font>
  
  a = sin²(Δφ/2) + cos φ1 ⋅ cos φ2 ⋅ sin²(Δλ/2)
+
===Hardware Design===
  c = 2 ⋅ atan2(√a, √(1−a))
+
'''Bluetooth Module Hardware Interfacing:'''
  d = R ⋅ c
+
  where,
+
We are using an HC-05 Bluetooth module to send and receive the data from our android application to Controller. The Bridge controller is connected to the Bluetooth module through the Serial interface(UART2) of SjOne board and we have configured HC-05 at 38400 baud rate 8-bit data and 1 stop bit using modules Communication Mode. Bridge Controller is connected to other SJOne Boards using CAN bus. The Bluetooth module communicates with the SJOne board using UART communication at 38400 baud rate.
        φ1 = Latitude of 1st Coordinate
 
        φ2 = Latitude of 2nd Coordinate
 
        λ1 = Longitude of 1st Coordinate
 
        λ2 = Longitude of 2nd Coordinate
 
        Δφ = φ2 - φ1
 
        Δλ = λ2 - λ1
 
        d  = distance between the two coordinates
 
        R  = earth’s radius (mean radius = 6,371km)
 
  Note: All the angles should be in radians.
 
  
==== GPS Heading angle calculation ====
 
  
[[File:Bearing Angle.JPG|500px|thumb|center|Bearing angle calculation ]]
+
[[ File: CmpE243_TechSavy_bridge_HC-05_pin_conf.png|679px|thumb|centre||HC-05 Module Hardware Interfacing]]
 +
<br>
  
With reference to the figure, the Heading angle for GPS is the angle between the line joining the two coordinates and the true north. To calculate it graphically, draw a vector pointing towards the destination coordinates from the start point coordinate and measure the angle between the vector and the true north. Use the below formula to calculate the angle mathematically.
+
===HC-05 Bluetooth module===
 +
HC-05 Bluetooth Module is used to set up wireless communication between the Car and the Android phone.
 +
This module is based on the Cambridge Silicon Radio BC417 2.4 GHz BlueTooth Radio chip. This is a complex chip which uses an external 8 Mbit flash memory
 +
It includes the Radio and Memory chips, 26 MHz crystal, antenna, and RF matching network.  
 +
The right section of the Bluetooth Board has connection pins for power and signals as well as a 5V to 3.3V Regulator, LED, and level shifting.  
  
  Heading angle(α) = atan2(sin Δλ ⋅ cos φ2 , cos φ1 ⋅ sin φ2 − sin φ1 ⋅ cos φ2 ⋅ cos Δλ)
+
* '''HC-05 PinOut'''
  where,
+
* EN:  In a case brought HIGH before power is applied, forces AT Command Setup Mode
        φ1 = Latitude of 1st Coordinate
+
* VCC: 5V Power
        φ2 = Latitude of 2nd Coordinate
+
* GND: Ground
        λ1 = Longitude of 1st Coordinate
+
* TXD: Serial Transmit pin connected to RXD2 of SJOne board
        λ2 = Longitude of 2nd Coordinate
+
* RXD: Serial Receive  pin connected to TXD2 of SJOne board
        Δλ = λ2 - λ1
+
* STATE: States if connected or not
  
==== GPS Checkpoint Navigation ====
+
* '''LED Blinking signals'''
The car reads the value of current coordinates from the GPS module to determine its Euclidean distance from the first checkpoint. It also checks the value on the compass to know which direction it should preferably move in i.e. Heading angle. The sensor readings help it ascertain that there isn't an obstacle to hinder its movement in the determined direction.
+
* Flashing RED Fast: Ready for Pairing with nearby Bluetooth device available
 +
* Flashing RED Slow: Paired and Connected
 +
=== Software Design ===
 +
[[File:tasktableBle.png]]
 +
[[File:Flowchart-reception-1.jpeg]]
 +
[[File:BleTransmission.png]]
  
We have selected 23 checkpoints on the location where the demo is going to takes place and we have filled these coordinates in a Checkpoint Array as shown below.
+
=== Technical Challenges ===
  
{|
+
* Android App was crashing due to the parsing function when there was no GPS data coming from the Bluetooth module. To solve this problem we added checks in the bridge controller to not to send GPS data if the GPS is not yet fixed.
|[[File:Checkpoints.JPG|thumb|400px|left|thumb|Selected Checkpoints]]
+
* Bridge controller's task was getting overrun when used snprint and printf in a task. (printf was just used for initial testing).Then after debugging, we found this problem and removed printf. snprintf and sprintf are working fine in 100Hz function.
|[[File:CheckPointsArray.JPG|thumb|350px|Right|thumb|Checkpoints Array]]
 
|}
 
  
<br>
+
<BR/>
  
* The Car begins navigating its way from its current location to the final destination using enlisted checkpoints. When the car arrives at a first checkpoint, then GEO Controller will look into its GPS checkpoints constant array to look for next nearest checkpoint.  
+
=='''Master Module'''==
* While selecting Checkpoint we are using Linear Searching technique to select next checkpoint which is closer to the current location and as well as closer to the final destination.
+
=== Hardware Design ===
 +
====Design and Implementation====
 +
*As name suffice, Master Node acts as the brain of the RC car and gives controlled signals to every other module. <br>
 +
*It manages the communication among all the modules, including Motor, Sensor, Geographical and Bridge Controller.<br>
 +
*Master receives periodically data from CAN bus based on message ID of the sender module.<br>
 +
*Below shows the connection of Master module on the CAN bus, connected with CAN Transceiver.
 +
[[ File: techsavy_master_can.png|679px|thumb|centre||Master-CAN Interfcaing]]
  
The Software state machine flow chart for GPS Navigation is shown below:
+
=== Software Design ===
[[File:Cmpe243_TechSavy_GPS_Navigation.JPG|600px|thumb|centre|GPS Checkpoint Navigation]]
+
*As the Master takes all the decisions, it has the highest priority and hence the lowest message Id on CAN DBC.
 +
*Figure illustrates the high-level bus flow from master to every module.
 +
[[ File: cmpe243_techsavy_master.gif|679px|thumb|centre||Master Control Flow]]
 +
====Implementation====
 +
'''Heartbeat Message of All Modules'''
 +
*As Master node handles all the communication from other modules, each node continuously sends its heartbeat to master, confirming that it is active and working properly.
 +
* If all the heartbeats are not received by the master, it sends STOP command to bridge so CAR doesn't run into a stage when any one of a node is not working. This mechanism provides us to eliminate running into an error state.
 +
* If the heartbeat is not received, Master handles this using MIA.
 +
*Code below displays heartbeat synchronization and MIA handling of all nodes.
  
==== Technical Challenges ====
+
  bool hbt_sync_from_all_node(void)
 
+
  {
* '''Issues 1''' - GPS doesn’t retain configuration settings; GPS module was forgetting its baud setting of 57600bps configuration settings after a long run testing of GPS module(we kept GPS for overnight testing to capture logs of GPRMC to check its location consistency) before the implementation of Distance calculation so after 4-5 hours its start giving Null values for latitude and longitude after reviewing the logs of the data captured that was giving garbage data as UART baud mismatching gives then it has to be configured again that means baud rate setting using PMTK command.
+
    is_hbt_sync_flag = sensor_hbt_sync & motor_hbt_sync & gps_hbt_sync & bridge_hbt_sync;
 +
    return is_hbt_sync_flag;
 +
  }
  
  '''Solution''' - As per recommendation is given in Arduino Data sheet we should use default baud settings of 9600 later we never faced this issue and it was giving a good fix.
+
  void master_mia_handler(void)
 +
  {
 +
    if (dbc_handle_mia_SENSOR_HEARTBEAT(&sensor_hbt, 25))
 +
    {
 +
        sensor_hbt_sync = false;
 +
    }
 +
    if (dbc_handle_mia_MOTOR_HEARTBEAT(&motor_hbt, 25))
 +
    {
 +
        motor_hbt_sync = false;
 +
    }
 +
    if (dbc_handle_mia_GPS_HEARTBEAT(&gps_hbt, 25))
 +
    {
 +
        gps_hbt_sync = false;
 +
    }
 +
    if (dbc_handle_mia_BRIDGE_HEARTBEAT(&bridge_hbt, 25))
 +
    {
 +
        bridge_hbt_sync = false;
 +
    }
 +
  }
  
*'''Issue 2''' - One of the most important thing with GPS is to get a quick fix. Our First Time to fix was coming approx 50seconds even in the open sky which is not good for self-driving car the moment engine of the car turns on we should have Coordinates of the car to navigate this to the destination location. So first Time to fix was one the hurdle for us.
+
[[File:master_led.jpg|400x300px|thumb|center|Heartbeat LED of all nodes on Master]]
  
  '''Solution''' - We have followed one of the Arduino Forum in which one of the experts give few tips on how to improve this GPS Fix issue and one of the tips worked for us was the of the Cell battery with the voltage of more than 2.89v. This resolves GPS fix the issue for us.  
+
=== Testing and Technical Challenges ===
 +
* Delay in sending steer command to the motor.
 +
** Initially there was some delay observed while receiving the sensor obstacle information and sending relevant command to motor, because of this synchronization problem we were suffering from the delayed response.
 +
** After plenty of hardware and software debugging, we noticed the buffer size of CAN RX/TX was much larger than required. It was corrected on sensor and motor side as well.
 +
* Taking time in reversing even though the reverse command was send
 +
** Motor took time to reverse as it has to break it's PID loop.
 +
** The solution to this was to send a stop command(0), before sending the reverse command.
 +
<Bullet or Headings of a module>
 +
==== Improper Unit Testing ====
 +
* The problem of CAN buffer described above was detected by Unit Testing itself.
 +
** Along with that bug, I found few more bugs from unit testing the code.
  
*'''Issue 3''' - Compass frequently losing its calibration when we were using CMPS11 in calibrated Mode.
+
<BR/>
  '''Solution''' - Using CMPS11 in default calibration mode helped us to get rid of this problem
 
  
*'''Issue 4''' Ahhhh!! Faced task overrun issue with GPS NMEA data. When we were using NMEA parsing and shortest path algorithm in one task or even in two different tasks code was crashing like anything. However, NMEA parsing and Path Finding algorithm were working fine.
+
=='''Mobile Application'''==
  '''Solution''' - Preet's easy parsing function(using sscanf) and his advice of using separate task using FreeRTOS helped us resolving this problem.
+
=== Software Design ===
  
*'''Issue 5''' During parsing of GPS Coordinates we have faced one issue with data type Float. Due to can transmission, we were using float data type for Latitude and longitude and what we have noticed that after getting data in string/char* and converting it to float then last two-three decimal places of latitude and longitude were changing frequently due to which Calculated distance from SOurce to destination was changing randomly even car is sitting at one location.
+
====1. Enable Bluetooth and Connect to bridge controller====
  
  '''Solution''' - GPS coordinates require double datatype so, we took coordinates as double and then while sending data on CAN we were typecasting that to float. As we were doing all calculation related to coordinates, distance and checkpoints calculations on GEO Controller itself. So after doing all the calculations in double, we were type casting data to float and we were sending that to MASTER & BRIDGE.
+
Wireless communication with the car takes places with communication over Bluetooth protocol. Android Application is created which provides an interface to exchange data and configure the car parameters.
  
 +
The android app connects to the HC-05 BLE module of the bridge controller. The Bluetooth ask the user for permission to access location and prompts to enable Bluetooth if it's already OFF. Our app is designed to connect to only TechSavy Bluetooth module and no other Bluetooth device to ease the setup of Bluetooth communication. A Bluetooth adapter connects to the HC-05 module and opens a Bluetooth Socket over which read and write messages are sent. A thread runs in the background which checks for available data, reads it and the data can then be processed. Data is written via the same Bluetooth socket. Refer to the following link to get started with Bluetooth on Android app and connection to HC-05 module ([http://mcuhq.com/27/simple-android-bluetooth-application-with-arduino-example]).
  
<BR/>
+
====2. Start/Stop Command and Log Sensor values====
  
=='''Bridge Controller Communication'''==
+
Start and Stop commands are sent to the RC car via the application. When Start/Stop button is pressed 1 or 0 commands are sent to the bridge controller when then transmits it to the CAN Bus for processing. Bluetooth status, Sensor Values, Motor parameters, GPS location, compass heading angle, distance to the checkpoint is displayed for debugging purpose. Sensor, GPS, motor Messages coming from CAN bus are decoded by the bridge controller and sent to the Android application as a string. The android app parses the string and categorizes the data to store it in appropriate variables. The data is then displayed as a text view in Bluetooth activity. To visit the Map Activity for setting destination and checkpoints a button is added. The map Activity opens on pressing the button.
Bridge Controller is used for communication between the SJOne board and the android phone using the HC-05 Bluetooth module. The main purpose of the bridge Controller is to receive the start/stop command and destination location from the Android app. Bridge controller will transmit all the sensor information and debug information and this information will be displayed on the android app.  
 
  
* BRIDGE CONTROLLER Git Link: <font color="blue"><U>[https://gitlab.com/tech-savycmpe243/cmpe243_techsavy_rc_car/tree/master/Bridge_Controller_Module]</U></font>
+
{|
 +
|[[File:Bluetooth_app.jpg|230px|thumb|The user is asked to enable Bluetooth]]
 +
|[[File:location1.jpg|230px|thumb|User should allow to enable Location]]
 +
|[[File:app_log2.jpeg|250px|thumb|Connecting to the Tech Savy CAR]]
 +
|[[File:app_log.jpeg|250px|thumb|Connected to the module]]
 +
|}
  
===Hardware Design===
+
====3. Map Activity====
'''Bluetooth Module Hardware Interfacing:'''
 
 
We are using an HC-05 Bluetooth module to send and receive the data from our android application to Controller. The Bridge controller is connected to the Bluetooth module through the Serial interface(UART2) of SjOne board and we have configured HC-05 at 38400 baud rate 8-bit data and 1 stop bit using modules Communication Mode. Bridge Controller is connected to other SJOne Boards using CAN bus. The Bluetooth module communicates with the SJOne board using UART communication at 38400 baud rate.
 
  
 +
The map activity is used in our app to show the current location of the car and set the destination marker which the car will navigate too. When map loads in the app the cars current location is indicated coming from the GPS as the source location (Red Marker). The desired location on the map can be set as the destination by long clicking on the map (Light Green marker).  The destination can be changed as desired by long pressing again. When the start button is pressed command 1 is sent to the CAN bus via Bluetooth to start the car. A thread starts in the background to indicate the current position of the car when the car moves (light blue marker). Also, a polyline is drawn between the source and destination marker to indicate the direction in which the car will move. For adding Google map to app refer the following [https://www.udemy.com/the-complete-android-oreo-developer-course/](Refer to Maps and geolocation section)
  
[[ File: CmpE243_TechSavy_bridge_HC-05_pin_conf.png|679px|thumb|centre||HC-05 Module Hardware Interfacing]]
+
[[File:Map1.jpeg|300px]]        [[File:Car_stop.jpeg|275px]]
<br>
+
 
 +
=== Testing and Technical Challenges ===
  
===HC-05 Bluetooth module===
+
1. We faced the problem of adding Bluetooth functionality in the app. There is a lack of tutorials online which shows how to develop an android app with Bluetooth capability and communicating with the HC-05 module. Fortunately, we found this webpage [http://mcuhq.com/27/simple-android-bluetooth-application-with-arduino-example] which helped us and Youtube videos of Coding with Mitch.
HC-05 Bluetooth Module is used to set up wireless communication between the Car and the Android phone.
 
This module is based on the Cambridge Silicon Radio BC417 2.4 GHz BlueTooth Radio chip. This is a complex chip which uses an external 8 Mbit flash memory
 
It includes the Radio and Memory chips, 26 MHz crystal, antenna, and RF matching network.
 
The right section of the Bluetooth Board has connection pins for power and signals as well as a 5V to 3.3V Regulator, LED, and level shifting.  
 
  
* '''HC-05 PinOut'''
+
2. It was difficult to design the UI on the app with little java and Android experience. We designing UI from mainly two resources [https://www.udemy.com/the-complete-android-oreo-developer-course/] [http://www.deitel.com/Books/Android/Android6forProgrammersAnAppDrivenApproach/tabid/3671/Default.aspx]and searching online for problems faced by us.
* EN:  In a case brought HIGH before power is applied, forces AT Command Setup Mode
 
* VCC: 5V Power
 
* GND: Ground
 
* TXD: Serial Transmit pin connected to RXD2 of SJOne board
 
* RXD: Serial Receive  pin connected to TXD2 of SJOne board
 
* STATE: States if connected or not
 
  
* '''LED Blinking signals'''
+
3. Initially, we developed the app such that we had to manually connect to a paired device to use Bluetooth functionality. This gave us problems while sending commands to the bridge controller. We solved this problem by fixing the device connection only to our HC-05 module and adding only a single Bluetooth connection button on the app bar for Bluetooth connection.
* Flashing RED Fast: Ready for Pairing with nearby Bluetooth device available
 
* Flashing RED Slow: Paired and Connected
 
=== Software Design ===
 
[[File:tasktableBle.png]]
 
[[File:Flowchart-reception-1.jpeg]]
 
[[File:BleTransmission.png]]
 
  
=== Technical Challenges ===
+
4. When we received too many sensor values and debug messages from the bridge controller continuously, the app was crashing due to the input buffer overflow. We solved this problem by adding a 1000ms sleep time to limit the input data coming to the app.
  
* Android App was crashing due to the parsing function when there was no GPS data coming from the Bluetooth module. To solve this problem we added checks in the bridge controller to not to send GPS data if the GPS is not yet fixed.
+
5. There was a requirement to continuously update a marker on the map indicating the current location of the car for user feedback. We achieved this using a thread in the background which updated cars position every 1 second.
* Bridge controller's task was getting overrun when used snprint and printf in a task. (printf was just used for initial testing).Then after debugging, we found this problem and removed printf. snprintf and sprintf are working fine in 100Hz function.
 
  
 
<BR/>
 
<BR/>
  
=='''Master Module'''==
+
=='''Suggestions for Future Students'''==
  
=== Hardware Design ===
+
* '''For Master Controller'''
====Design and Implementation====
+
** Don't make your obstacle avoidance complex by implementing reverse condition. Just keep your code simple.
*As name suffice, Master Node acts as the brain of the RC car and gives controlled signals to every other module. <br>
+
** One good approach a developer should follow is to unit test their own code. Would you buy a product which is suppose to be tested later?
*It manages the communication among all the modules, including Motor, Sensor, Geographical and Bridge Controller.<br>
+
** Remember the KISS approach when you code. (Keep It Simple and Stupid).
*Master receives periodically data from CAN bus based on message ID of the sender module.<br>
+
** For this controller, one should know the basics in C/ C++ and some good debugging skills. Because if you don't have one, you will eventually end up spending more time debugging your problem.
*Below shows the connection of Master module on the CAN bus, connected with CAN Transceiver.
+
* '''For Hardware Team'''
[[ File: techsavy_master_can.png|679px|thumb|centre||Master-CAN Interfcaing]]
+
** Order Hardware and Components as early as possible.
 
+
** Select components wisely don't try to save money on this part of the project as bad quality hardware can't help you even with best software implementation.
=== Software Design ===
+
** Try to power up all modules using 6V coming from LiPo battery. Use IC boosters for converting 6V to 5V and 3.3V. This way there won't be a need of separate power bank and overall weight will be reduced.
*As the Master takes all the decisions, it has the highest priority and hence the lowest message Id on CAN DBC.
+
** While designing PCB keep the tracing width of power lines to 1 mm so that sufficient current can be pass through it.
*Figure illustrates the high-level bus flow from master to every module.
+
** PCB spacing should be 12-15 mil.
[[ File: cmpe243_techsavy_master.gif|679px|thumb|centre||Master Control Flow]]
+
** To reduce the magnetic interference from DC Motor, place the compass on the center or near the front side of the car at a height using standoffs.
====Implementation====
+
** Another alternative to standoffs could be implementing ground rings for compass and GPS Antenna which allows passing the EMI directly to the ground.
'''Heartbeat Message of All Modules'''
+
** Get more samples of CAN transceiver IC's as it can get damaged easily.
*As Master node handles all the communication from other modules, each node continuously sends its heartbeat to master, confirming that it is active and working properly.  
+
* '''For SENSOR Controller Team'''
* If all the heartbeats are not received by the master, it sends STOP command to bridge so CAR doesn't run into a stage when any one of a node is not working. This mechanism provides us to eliminate running into an error state.
+
** LIDAR - It has some limitations when tests/demo takes place in bright sunlight. when direct light falls on it, so gives faulty readings.
* If the heartbeat is not received, Master handles this using MIA.
+
** LIDAR Consumes more power, hence need a separate power source for it due to which battery consumption of overall CAR is double as compared to the CAR use ultrasonic sensors for obstacle detection.
*Code below displays heartbeat synchronization and MIA handling of all nodes.
+
** LIDAR is not even cost effective hence should use Ultrasonic instead we realized it very late.
 +
** Sensor Implementation doesn't need any averaging or complex algorithms.
 +
* '''For GEO Controller Team'''
 +
** Suggestions for GEO Controller software development is used FreeRTOS separate Tasks instead of using periodic tasks for NMEA receiving and parsing.
 +
** For GPS Checkpoint navigation use simple and stupid coding no need to implement Dijkstra and complex algorithms for short distance calculation on Geo Controller linear or binary searching technique is enough to implement it successfully.
 +
** For Compass use default calibration mode no need to add any checks and calibrations. Factory mode should be enough to get accurate results.
 +
* '''For Motor Controller Team'''
 +
** Use global pointers while using PWM drivers of SJONE board and set the frequency appropriately before testing it on motor(50Hz or 100Hz is fine).
 +
** Calibrate the ESC first for any RC car you purchase and get that right or the DC motor wont work.
 +
** Clear the CAN buffer periodically or the car might react to the commands with some delay.
 +
* '''Tips for getting GOOD Grades and to remain in top 3 teams'''
 +
** Select your team mates wisely, and make sure every one dedicates them self for this project.
 +
** Be an active member of your team and review rubrics every week before going to demonstrate your CAR.
 +
** As soon as the professor mentioned about the project please start working on the project right from the beginning otherwise at the end you have struggled with finals and you will be left with less time for testing and you have to struggle in demo.
 +
** Although you can get lots of information from seniors still don't take this project light this is a really interesting and challenging project.
 +
 
 +
=='''Conclusion'''==
 +
 
 +
[[File:Compass_UnitTesting.JPG|300px|thumb|right|Unit Testing Report Example]]
  
  bool hbt_sync_from_all_node(void)
+
It was a really great working experience for all of us. We were really thrilled from the beginning that we will be working on something that is quite relevant in the industries these days. We worked as a team of eight which helped us all to know the importance of team-work and co-ordination. We learned many great stuff like
  {
 
    is_hbt_sync_flag = sensor_hbt_sync & motor_hbt_sync & gps_hbt_sync & bridge_hbt_sync;
 
    return is_hbt_sync_flag;
 
  }
 
  
  void master_mia_handler(void)
+
* CAN bus:
  {
+
** Using this bus, we were able to communicate with five devices connected which each other.
    if (dbc_handle_mia_SENSOR_HEARTBEAT(&sensor_hbt, 25))
+
** Also, we learnt how to debug and interpret CAN message using BusMaster.
    {
+
* LIDAR and ultrasonic sensor:
        sensor_hbt_sync = false;
+
** At start we felt LIDAR would be easy to use because it gives us the obstacle data for all 360 degree. But as we started using it, we found out that keeping wider angle does not give us accurate data. Then we realised that at after certain distance the angles intersect with each other because of angle spread and we get the same reading for both angle zone. So we selected our angle zone precisely and accurately by doing some trials and error.
    }
+
* PCB designing:
    if (dbc_handle_mia_MOTOR_HEARTBEAT(&motor_hbt, 25))
+
** We realised that using GPP for long term is not a good idea because every time our car crashed, there were some breakdown in the wires and our CAN bus stopped working. Initially we spent a lot of time debugging hardware and doing soldering.
    {
+
** So the hardware team started designing the PCB, and when our PCB was mounted on car, we spent hardly any time debugging the hardware.
        motor_hbt_sync = false;
+
* We learnt about NMEA data packets while working with GPS and came to know how google map Application actaully works with the help of GPS satellites in view for navigation.
    }
+
* Unit testing : Unity and cmock framework are great tools for learning and it helped us to get great results in less amount of time. Unit testing of code is a must and should be adopted.
    if (dbc_handle_mia_GPS_HEARTBEAT(&gps_hbt, 25))
+
* Git : We learnt all the basic of GIT and it plays an important to role for source code versioning.
    {
+
There were a lot of problems while doing this project but it was a steep learning curve.
        gps_hbt_sync = false;
+
In the end we were able to achieve our objective with really good results.
    }
+
 
    if (dbc_handle_mia_BRIDGE_HEARTBEAT(&bridge_hbt, 25))
+
=== Project Video ===
    {
+
[https://youtu.be/tvjshIk-hdA Tech Savy Project Video]
        bridge_hbt_sync = false;
+
 
    }
+
=== Project Source Code ===
  }
+
*  Git Project Link: <font color="blue">[https://gitlab.com/tech-savycmpe243/cmpe243_techsavy_rc_car]</font><br>
  
[[File:master_led.jpg|400x300px|thumb|center|Heartbeat LED of all nodes on Master]]
+
=='''References'''==
  
=== Testing and Technical Challenges ===
+
=== Acknowledgement ===
* Delay in sending steer command to the motor.
+
We would like to express our gratitude to Professor Preetpal Kang for generously sharing his time and knowledge with us and guiding us through the completion of this project.
** Initially there was some delay observed while receiving the sensor obstacle information and sending relevant command to motor, because of this synchronization problem we were suffering from the delayed response.
+
We would also like to thank the Pratap(ISA) for their valuable advice and constructive feedback.
** After plenty of hardware and software debugging, we noticed the buffer size of CAN RX/TX was much larger than required. It was corrected on sensor and motor side as well.
 
* Taking time in reversing even though the reverse command was send
 
** Motor took time to reverse as it has to break it's PID loop.
 
** The solution to this was to send a stop command(0), before sending the reverse command.
 
<Bullet or Headings of a module>
 
==== Improper Unit Testing ====
 
* The problem of CAN buffer described above was detected by Unit Testing itself.
 
** Along with that bug, I found few more bugs from unit testing the code.
 
  
<BR/>
+
=== References Used ===
  
=='''Mobile Application'''==
+
====== LIDAR ======
=== Software Design ===
+
* [http://www.slamtec.com/en/Lidar/A1 RPLidar Documentation]
 
+
====== PID Control ======
====1. Enable Bluetooth and Connect to bridge controller====
+
* [http://ctms.engin.umich.edu/CTMS/index.php?example=Introduction&section=ControlPID PID Controller Design]
 
+
* [https://robotics.stackexchange.com/questions/167/what-are-good-strategies-for-tuning-pid-loops  Good Strategies for PID Tuning]
Wireless communication with the car takes places with communication over Bluetooth protocol. Android Application is created which provides an interface to exchange data and configure the car parameters.
+
====== LCD ======
 
+
* [http://www.4dsystems.com.au/downloads/Application-Notes/4D-AN-00017_R_1_01.pdf Connecting LCD to Host]
The android app connects to the HC-05 BLE module of the bridge controller. The Bluetooth ask the user for permission to access location and prompts to enable Bluetooth if it's already OFF. Our app is designed to connect to only TechSavy Bluetooth module and no other Bluetooth device to ease the setup of Bluetooth communication. A Bluetooth adapter connects to the HC-05 module and opens a Bluetooth Socket over which read and write messages are sent. A thread runs in the background which checks for available data, reads it and the data can then be processed. Data is written via the same Bluetooth socket. Refer to the following link to get started with Bluetooth on Android app and connection to HC-05 module ([http://mcuhq.com/27/simple-android-bluetooth-application-with-arduino-example]).
+
====== Android GUI ======
 
+
[https://developer.android.com/studio/write/image-asset-studio.html Create App Icons with Image Asset Studio]
====2. Start/Stop Command and Log Sensor values====
+
[https://developer.android.com/training/basics/fragments/index.html Building a Dynamic UI with Fragments]
 
+
[https://www.youtube.com/playlist?list=PL6gx4Cwl9DGBsvRxJJOzG4r4k_zLKrnxl Android Tutorial]
Start and Stop commands are sent to the RC car via the application. When Start/Stop button is pressed 1 or 0 commands are sent to the bridge controller when then transmits it to the CAN Bus for processing. Bluetooth status, Sensor Values, Motor parameters, GPS location, compass heading angle, distance to the checkpoint is displayed for debugging purpose. Sensor, GPS, motor Messages coming from CAN bus are decoded by the bridge controller and sent to the Android application as a string. The android app parses the string and categorizes the data to store it in appropriate variables. The data is then displayed as a text view in Bluetooth activity. To visit the Map Activity for setting destination and checkpoints a button is added. The map Activity opens on pressing the button.
+
====== Google Maps ======
 
+
* [https://developer.android.com/training/maps/index.html Adding Maps]
{|
+
* [https://developers.google.com/maps/documentation/android-api/marker Markers]
|[[File:Bluetooth_app.jpg|230px|thumb|The user is asked to enable Bluetooth]]
+
* [https://developers.google.com/maps/documentation/directions/?authuser=1 Google Maps Directions API]
|[[File:location1.jpg|230px|thumb|User should allow to enable Location]]
 
|[[File:app_log2.jpeg|250px|thumb|Connecting to the Tech Savy CAR]]
 
|[[File:app_log.jpeg|250px|thumb|Connected to the module]]
 
|}
 
 
 
====3. Map Activity====
 
 
 
The map activity is used in our app to show the current location of the car and set the destination marker which the car will navigate too. When map loads in the app the cars current location is indicated coming from the GPS as the source location (Red Marker). The desired location on the map can be set as the destination by long clicking on the map (Light Green marker).  The destination can be changed as desired by long pressing again. When the start button is pressed command 1 is sent to the CAN bus via Bluetooth to start the car. A thread starts in the background to indicate the current position of the car when the car moves (light blue marker). Also, a polyline is drawn between the source and destination marker to indicate the direction in which the car will move. For adding Google map to app refer the following [https://www.udemy.com/the-complete-android-oreo-developer-course/](Refer to Maps and geolocation section)
 
 
 
[[File:Map1.jpeg|300px]]        [[File:Car_stop.jpeg|275px]]
 
 
 
=== Testing and Technical Challenges ===
 
 
 
1. We faced the problem of adding Bluetooth functionality in the app. There is a lack of tutorials online which shows how to develop an android app with Bluetooth capability and communicating with the HC-05 module. Fortunately, we found this webpage [http://mcuhq.com/27/simple-android-bluetooth-application-with-arduino-example] which helped us and Youtube videos of Coding with Mitch.
 
 
 
2. It was difficult to design the UI on the app with little java and Android experience. We designing UI from mainly two resources [https://www.udemy.com/the-complete-android-oreo-developer-course/] [http://www.deitel.com/Books/Android/Android6forProgrammersAnAppDrivenApproach/tabid/3671/Default.aspx]and searching online for problems faced by us.
 
 
 
3. Initially, we developed the app such that we had to manually connect to a paired device to use Bluetooth functionality. This gave us problems while sending commands to the bridge controller. We solved this problem by fixing the device connection only to our HC-05 module and adding only a single Bluetooth connection button on the app bar for Bluetooth connection.
 
 
 
4. When we received too many sensor values and debug messages from the bridge controller continuously, the app was crashing due to the input buffer overflow. We solved this problem by adding a 1000ms sleep time to limit the input data coming to the app.
 
 
 
5. There was a requirement to continuously update a marker on the map indicating the current location of the car for user feedback. We achieved this using a thread in the background which updated cars position every 1 second.
 
 
 
<BR/>
 
 
 
=='''Suggestions for Future Students'''==
 
 
 
* '''For Master Controller'''
 
** Don't make your obstacle avoidance complex by implementing reverse condition. Just keep your code simple.
 
** One good approach a developer should follow is to unit test their own code. Would you buy a product which is suppose to be tested later?
 
** Remember the KISS approach when you code. (Keep It Simple and Stupid).
 
** For this controller, one should know the basics in C/ C++ and some good debugging skills. Because if you don't have one, you will eventually end up spending more time debugging your problem.
 
* '''For Hardware Team'''
 
** Order Hardware and Components as early as possible.
 
** Select components wisely don't try to save money on this part of the project as bad quality hardware can't help you even with best software implementation.
 
** Try to power up all modules using 6V coming from LiPo battery. Use IC boosters for converting 6V to 5V and 3.3V. This way there won't be a need of separate power bank and overall weight will be reduced.
 
** While designing PCB keep the tracing width of power lines to 1 mm so that sufficient current can be pass through it.
 
** PCB spacing should be 12-15 mil.
 
** To reduce the magnetic interference from DC Motor, place the compass on the center or near the front side of the car at a height using standoffs.
 
** Another alternative to standoffs could be implementing ground rings for compass and GPS Antenna which allows passing the EMI directly to the ground.
 
** Get more samples of CAN transceiver IC's as it can get damaged easily.
 
* '''For SENSOR Controller Team'''
 
** LIDAR - It has some limitations when tests/demo takes place in bright sunlight. when direct light falls on it, so gives faulty readings.
 
** LIDAR Consumes more power, hence need a separate power source for it due to which battery consumption of overall CAR is double as compared to the CAR use ultrasonic sensors for obstacle detection.
 
** LIDAR is not even cost effective hence should use Ultrasonic instead we realized it very late.
 
** Sensor Implementation doesn't need any averaging or complex algorithms.
 
* '''For GEO Controller Team'''
 
** Suggestions for GEO Controller software development is used FreeRTOS separate Tasks instead of using periodic tasks for NMEA receiving and parsing.
 
** For GPS Checkpoint navigation use simple and stupid coding no need to implement Dijkstra and complex algorithms for short distance calculation on Geo Controller linear or binary searching technique is enough to implement it successfully.
 
** For Compass use default calibration mode no need to add any checks and calibrations. Factory mode should be enough to get accurate results.
 
* '''For Motor Controller Team'''
 
** Use global pointers while using PWM drivers of SJONE board and set the frequency appropriately before testing it on motor(50Hz or 100Hz is fine).
 
** Calibrate the ESC first for any RC car you purchase and get that right or the DC motor wont work.
 
** Clear the CAN buffer periodically or the car might react to the commands with some delay.
 
* '''Tips for getting GOOD Grades and to remain in top 3 teams'''
 
** Select your team mates wisely, and make sure every one dedicates them self for this project.
 
** Be an active member of your team and review rubrics every week before going to demonstrate your CAR.
 
** As soon as the professor mentioned about the project please start working on the project right from the beginning otherwise at the end you have struggled with finals and you will be left with less time for testing and you have to struggle in demo.
 
** Although you can get lots of information from seniors still don't take this project light this is a really interesting and challenging project.
 
 
 
=='''Conclusion'''==
 
 
 
[[File:Compass_UnitTesting.JPG|300px|thumb|right|Unit Testing Report Example]]
 
It was a really great working experience for all of us. We were really thrilled from the beginning that we will work on something that is quite relevant in the industries these days. We worked as a team of 8 which helped us all to know the importance of team-work and co-ordination. We learned much great stuff like
 
 
 
* CAN bus communication,
 
* LIDAR, ultrasonic sensors,
 
* PCB designing, GPS, Compass, Android Application development.
 
* Unit testing with 100% coverage accelerated our development significantly and it helped us to get great results in less amount of time. 
 
* We also learned how to debug and interpret CAN message using BusMaster.
 
* Git also plays an important role to maintain the source code. There were a lot of problems while doing this project but it was a steep learning curve. In the end, we were able to achieve our objective with really good results.
 
 
 
=== Project Video ===
 
[https://youtu.be/tvjshIk-hdA Tech Savy Project Video]
 
 
 
=== Project Source Code ===
 
* [https://sourceforge.net/projects/sjsu/files/CmpE_S2016/ Sourceforge Source Code Link]
 
 
 
* Git Project Link: <font color="blue">[https://gitlab.com/tech-savycmpe243/TechSavy Tech Savy ]</font><br>
 
 
 
=='''References'''==
 
 
 
=== Acknowledgement ===
 
We would like to express our gratitude to Professor Preetpal Kang for generously sharing his time and knowledge with us and guiding us through the completion of this project.
 
We would also like to thank the Pratap(ISA) for their valuable advice and constructive feedback.
 
  
=== References Used ===
+
====== PCB Design using DipTrace ======
 
+
* [https://diptrace.com/books/tutorial.pdf DipTrace Tutorial]
====== LIDAR ======
+
* [https://diptrace.com/forum/viewtopic.php?t=11533 Diptrace Forum FAQ-1]
* [http://www.slamtec.com/en/Lidar/A1 RPLidar Documentation]
+
* [https://diptrace.com/forum/viewtopic.php?t=10853 DipTrace Forum FAQ-2]
====== PID Control ======
 
* [http://ctms.engin.umich.edu/CTMS/index.php?example=Introduction&section=ControlPID PID Controller Design]
 
* [https://robotics.stackexchange.com/questions/167/what-are-good-strategies-for-tuning-pid-loops  Good Strategies for PID Tuning]
 
====== LCD ======
 
* [http://www.4dsystems.com.au/downloads/Application-Notes/4D-AN-00017_R_1_01.pdf Connecting LCD to Host]
 
====== Android GUI ======
 
* [https://developer.android.com/studio/write/image-asset-studio.html Create App Icons with Image Asset Studio]
 
*  [https://developer.android.com/training/basics/fragments/index.html Building a Dynamic UI with Fragments]
 
*  [https://www.youtube.com/playlist?list=PL6gx4Cwl9DGBsvRxJJOzG4r4k_zLKrnxl Android Tutorial]
 
====== Google Maps ======
 
* [https://developer.android.com/training/maps/index.html Adding Maps]
 
* [https://developers.google.com/maps/documentation/android-api/marker Markers]
 
* [https://developers.google.com/maps/documentation/directions/?authuser=1 Google Maps Directions API]
 
  
 
==== Datasheets ====
 
==== Datasheets ====

Latest revision as of 21:05, 10 July 2020


LOGO


Contents

Tech Savy RC Car

Tech_Savy Side Open view
Tech_Savy View
Tech_Savy Top Open view

Abstract

In this project our main aim to build a Self-Navigating Car named Tech Savy, that navigates from a source location to a selected destination by avoiding obstacles in its path using sensors and motors.

Main Building Blocks of Tech Savy

Introduction & Objectives

The key features support by the system are

1. A Google-map based Android application is developed which will update the live location of RC car given by GPS to Bridge over Bluetooth.Android app is used to get information from all the Modules and will show live data of MOTOR, SENSORS, GPS and COMPASS and we can set the final destination so that car can drive to the destination.

2. The car will be integrated with the GPS, Compass, Bluetooth, multiple sensors such as Ultrasonic sensors and RPM sensors to fulfill the purpose of navigation, obstacle detection, and avoidance

3. LIDAR and Ultrasonic Sensor is used for obstacle detection and avoidance in all the angles in the view of 360 degrees.

4. Motor drives the car by Route Calculation done on GPS using the shortest distance path algorithm between current location and destination and connects to the self-driving RC car via Bluetooth to send the GPS Coordinates and Maneuvering to the selected destination and Self- Adjusting the speed of the car on Ramp.

5. LEDs and LED Display are used for debugging and to get all relevant information about the status of the car, in real time and LCD Display is used to give more detailed information related to the car.

The system is built on FreeRTOS running on LPC1758 SJOne controller and Android application. The main building blocks of Tech Savy are the five controllers communicating through High Speed CAN network designed to handle dedicated tasks. The controllers integrate various sensors that are used for navigation of the car.

CAR Objectives

     1. Master Controller - Handles the Route Manuevering,Path Planning and Obstacle Avoidance 
     2. Sensor Controller - Detects the surrounding objects
     3. Geo Controller - Provides current location in the form of coordinates and navigate car using CMPS11
     4. Motor Controller - controls the movement of the Car.
     5. Bridge controller - Interfaces the system using Bluetooth to an Android application. 

Team Objectives

     1. Learn each and every module as much as possible, in order to develop an industrial product.
     2. Achieve 100% code coverage, during unit testing. 
     3. Document and track all the bugs encountered during development, unit testing, and field testing.
System Architecture
Android Application

Team Members & Technical Responsibilities

TEAM TECH SAVY


Administrative Responsibilities

Administrative Roles
  • Team Lead
Aakash Chitroda
  • Finance Manager
Halak Vyas
  • Git Repository Manager
Vatsal Makani
  • Wiki Report Manager
Vidushi Jain
  • Bill of Materials Manager
Jay Parsana

Team Deliverables Schedule

WEEK

START DATE

END DATE

TASK DETAILS

STATUS

1 26 Feb 2019 4 March 2019
  • 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
Completed
Completed
Completed
Completed
2 05 March 2019 12 March 2019
  • Create a Bill of Materials.
  • Select and order an RC car.
  • Make Repo on Gitlab for all modules - Follow Naming Convention.
Completed
Completed
Completed
3 13 March 2019 19 March 2019
  • Select Part Number for Sensors (Halak, Aakash)
  • Designing and deciding PCB tool(Prashant, Vatsal)
  • Finalizing GPS module by doing some research (Vidushi)
  • Finalize and order LCD (Aakash, Vidushi)
  • Finalize Motor and Order it (Vatsal)
  • Environmental setup of Android (Saumil, Akshata)
Completed
Completed
Completed
Completed
Completed
Completed
4 20 March 2019 26 March 2019
  • Understand DBC and implement the DBC file compatible with all the controllers.
  • Test motor driving in different situations, begin to listen to CAN for controls.
  • 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.
  • 03/26/2019 DBC File
  • 03/26/2019 DEMO: CAN communication between controllers.
Completed
Completed
Completed
Completed
Completed
Completed
5 27 March 2019 09 April 2019
  • Check and Resolve power issue for RC Car.
  • Finalize high-level system block diagram and control scheme.
  • Circuit Simulation in Diptrace Tool.
  • PCB Layout Design in Diptrace Tool.
  • Finalize Components placement on PCB.
  • Establish a connection over Bluetooth and Android app.
  • Establish a communication between Bluetooth devices.
  • Interfacing of ultrasonic sensors to the SJOne board and check for basic functionality.
  • Interface and get the reading of Lidar sensor with SJOne over UART.
  • Chalk out the Message IDs based on the priority of the messages and the data to be sent across nodes.
  • Interface of Servo & DC motor to the SJOne board and check for basic functionality.
  • Interface Compass module with SJOne board using I2C serial bus.
  • Interface bluetooth HC-05 module with SJOne board using serial Communication.
  • Configure bluetooth HC-05 module name as Tech Savy using HC-05 Communication Mode.
  • Explore UI designing of LCD.
  • Finish motor controller API. Test motor driving in different situations, begin to listen to CAN for controls.
  • Add a TextView for displaying the Bluetooth connection status in Android App.
Completed
Completed
Completed
Completed
Completed
Completed
Completed
Completed
Completed
Completed
Completed
Completed
Completed
Completed
Completed
Completed
Completed
6 10 April 2019 16 April 2019
  • Parse data of Lidar Sensor depending on distance and angle and send it to master using dbc.
  • 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.
  • 16 April 2019 DEMO: Motors driven by wheel feedback and sensors, Basic obstacle avoidance.
  • Final Wiki Schedule.
Completed
Completed
Completed
Completed
Completed
Completed
Completed
Completed
Completed
Completed
Completed
7 17 April 2019 23 April 2019
  • 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.
  • Update Wiki Schedule with Test Reports.
Completed
Completed
Completed
Completed
Completed
Completed
Completed
Completed
Completed
Completed
Completed
Completed
In Progress
Completed
Completed
8 24 April 2019 30 April 2019
  • 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
Completed
Completed
Completed
Completed
Completed
Completed
Completed
Completed
Completed
Completed
Completed
Completed
Completed
9 1 May 2019 7 May 2019
  • 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.
Completed
Completed
Completed
Completed
Completed
Completed
Completed
10 8 May 2019 21 May 2019
  • 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.
Completed
Completed
Completed
Completed
Completed
11 22 May 2019
  • DEMO: Final Project
  • SUBMISSION: Final Project Wiki
Completed
Completed

BILL OF MATERIALS (GENERAL PARTS)

PART NAME

PART MODEL & SOURCE

QUANTITY

COST PER UNIT (USD)

  • Micro-Controller Eval-Boards
  • LPC 1758 (Purchased from Preet Kang)
  • 5
  • 80.00
  • RC Car
  • 1
  • 205.99
  • Lithium-Ion Battery
  • 1
  • 74.95
  • Lithium-Ion Battery 2
  • 1
  • 69.95
  • RC Car Battery Charger
  • 1
  • 49.95
  • Bluetooth Breakout Board
  • 1
  • 8.49
  • RC Car Display
  • 1
  • 79.00
  • Ultrasonic Sensors
  • 2
  • 30.00
  • RP-LIDAR Sensor
  • 1
  • 99.00
  • GPS Antenna
  • 1
  • 5.00
  • CAN Transreceivers
  • 20
  • FREE
  • Compass
  • 2
  • 30.00
  • RPM Sensor
  • 1
  • 10.00
  • GPS Breakout Board
  • 1
  • 43.00
  • PCB parts and other Miscellaneous parts
  • Anchor Electronics and Digikey
  • 1
  • 130.00
  • PCB Fabrication
  • 5
  • 29.53


Printed Circuit Board

Design And Architecture

We designed the custom PCB using DipTrace Software in which we implemented connections for all the controller modules(SJOne Board LPC1758) all communicating/sending data via CAN bus. The data is sent by individual sensors to the respective controllers. GPS and Compass are connected to Geographical Controller. RPM sensor, DC and Servo Motors are connected to Motor Controller. Ultrasonic and Lidar are connected to Sensor Controller. LCD is connected to Motor Controller. Bluetooth is connected to Bridge Controller. CAN Bus is implemented using CAN Transceivers MCP2551 terminated by 120Ohms; with PCAN for monitoring CAN Debug Messages and Data.

Power Section

We implemented separate power modules for LIDAR and remaining modules of the PCB. The micro USB mini B supplies 5V to LIDAR Motor and Scanner (max current rating estimated @ 1A). Another power is supplied through USB 2.0 Type A connector with a rating of 5V@2A. Since GPS requires 3.3V, we have used a linear regulator REG1117-3.3. All the parts are through-hole components.

Fabrication

PCB was sent to fabrication to JLCPCB China which provided PCB with MOQ of 5 with the lead time of 1 week. We implemented 2 layers of PCB with most of the parts in top layer. We implemented rectangular header connector for SJOne boards, RPM sensor, DC & Servo Motor and GPS modules on the bottom layer.

Challenges

There were 2 iterations of this board. The first one was designed without validation and had problems with orientation of the SJOne board header & pin connections. We also need to change the header for LCD since it was having different pitch.This design lacked several necessary power connections and was limited by functionality. These problems were fixed in the 2nd iteration.


PCB Layout Design in DipTrace
PCB Top Layer
PCB Bottom Layer
















CAN Communication

  • As the DBC file shows, master is given the highest priority after bridge start/stop command message.
  • All messages from every controller are send to Bridge and Motor as well along with Master, to display it on Android app and LCD Controller for debugging and testing.
  • Every controller is also sending Initialization Debug messages over CAN, to verify it on BusMaster.
  • 1Hz task is used to check CAN_bus_off() condition, along with send heartbeat and debug message messages over can.
  • As master is the major receiver of all the signals, it perform MIA handling of all necessary signals along with heartbeat as well.
  • We have also used plenty of LEDs for confirming we get correct heartbeat and data.
  • The code for master MIA initialization is as shown below,
 const uint32_t                             BRIDGE_NODE__MIA_MS = 3000;
 const BRIDGE_NODE_t                        BRIDGE_NODE__MIA_MSG = { 0, {0} };
 const uint32_t                             SENSOR_NODE__MIA_MS = 3000;
 const SENSOR_NODE_t                        SENSOR_NODE__MIA_MSG = { 0 };
 const uint32_t                             GPS_LOCATION__MIA_MS = 3000;
 const GPS_LOCATION_t                       GPS_LOCATION__MIA_MSG = { 37.3686485, -121.9153289, {0} };
 const uint32_t                             COMPASS__MIA_MS = 3000;
 const COMPASS_t                            COMPASS__MIA_MSG = { 37.3686485, -121.9153289, 0.0, {0} };
 const uint32_t                             SENSOR_HEARTBEAT__MIA_MS = 3000;
 const SENSOR_HEARTBEAT_t                   SENSOR_HEARTBEAT__MIA_MSG = {0, {0}};
 const uint32_t                             MOTOR_HEARTBEAT__MIA_MS = 3000;
 const MOTOR_HEARTBEAT_t                    MOTOR_HEARTBEAT__MIA_MSG = {0, {0}};
 const uint32_t                             GPS_HEARTBEAT__MIA_MS = 3000;
 const GPS_HEARTBEAT_t                      GPS_HEARTBEAT__MIA_MSG = {0, {0}};
 const uint32_t                             BRIDGE_HEARTBEAT__MIA_MS = 3000;
 const BRIDGE_HEARTBEAT_t                   BRIDGE_HEARTBEAT__MIA_MSG = {0, {0}};

Hardware Design

The CAN bus hardware implementation between all the controller module for this project is shown below. It is necessary to terminate the CAN bus at 120 Ohms to prevent any signal reflections.

PCB Layout Design in DipTrace

We have implemented some LEDs for indicating the heartbeat signals sent by the master, sensor readings and motor movements. Below is the table explaining the LEDs in PCBs along with the color, pin and signal description


DBC File

A Link to the DBC file that defines the CAN communication of the system is as follows: DBC link on GitLab

DBC is a format that enables fewer hassles while developing code to either interpret data received or send data over the CAN bus. This project used DBC effectively.

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_: MASTER BRIDGE MOTOR SENSOR GPS DBG


BO_ 103 BRIDGE_NODE: 1 BRIDGE
 SG_ BRIDGE_START_cmd : 0|1@1+ (1,0) [0|1] "" MASTER,MOTOR

BO_ 104 CAR_CONTROL: 4 MASTER
 SG_ MOTOR_DRIVE_cmd : 0|2@1+ (1,0) [0|0] "" MOTOR,BRIDGE
 SG_ MOTOR_STEER_cmd : 2|15@1+ (0.1,-90.0) [-90|90] "" MOTOR,BRIDGE
 SG_ MOTOR_kph : 17|12@1+ (0.01,0) [0.00|20.00] "kph" MOTOR,BRIDGE
 
BO_ 105 SENSOR_NODE: 5 SENSOR
 SG_ SENSOR_FRONT_cm : 0|10@1+ (1,0) [0|645] "cm" MASTER,MOTOR,BRIDGE
 SG_ LIDAR_Obstacle_FRONT : 10|3@1+ (1,0) [0|0] "" MASTER,MOTOR,BRIDGE
 SG_ LIDAR_Obstacle_RIGHT : 13|3@1+ (1,0) [0|0] "" MASTER,MOTOR,BRIDGE
 SG_ LIDAR_Obstacle_LEFT : 16|3@1+ (1,0) [0|0] "" MASTER,MOTOR,BRIDGE
 SG_ LIDAR_Obstacle_BACK : 19|3@1+ (1,0) [0|0] "" MASTER,MOTOR,BRIDGE
 SG_ LIDAR_Obstacle_BACK_RIGHT : 22|3@1+ (1,0) [0|0] "" MASTER,MOTOR,BRIDGE
 SG_ LIDAR_Obstacle_BACK_LEFT : 25|3@1+ (1,0) [0|0] "" MASTER,MOTOR,BRIDGE

BO_ 106 MOTOR_NODE: 2 MOTOR
 SG_ MOTOR_SPEED_kph : 0|12@1+ (0.01,0) [0.00|20.00] "kph" MASTER,BRIDGE
 
BO_ 107 BRIDGE_CHECKPOINTS: 8 BRIDGE
 SG_ CHECKPOINT_LAT_deg : 0|28@1+ (0.000001,-90.000000) [-90|90] "Degrees" MASTER,GPS,MOTOR
 SG_ CHECKPOINT_LONG_deg : 28|29@1+ (0.000001,-180.000000) [-180|180] "Degrees" MASTER,GPS,MOTOR
 
BO_ 108 GPS_LOCATION: 8 GPS
 SG_ CURRENT_LAT_deg : 0|28@1+ (0.000001,-90.000000) [-90|90] "Degrees" MASTER,BRIDGE,MOTOR
 SG_ CURRENT_LONG_deg : 28|29@1+ (0.000001,-180.000000) [-180|180] "Degrees" MASTER,BRIDGE,MOTOR
 
BO_ 109 COMPASS: 8 GPS
 SG_ CMP_HEADING_deg : 0|12@1+ (0.1,0) [0|359.9] "Degrees" MASTER,BRIDGE,MOTOR
 SG_ CMP_BEARING_deg : 12|12@1+ (0.1,0) [0|359.9] "Degrees" MASTER,BRIDGE,MOTOR
 SG_ CMP_DISTANCE_meters : 24|17@1+ (0.01,0) [0|0] "Meters" MASTER,MOTOR,BRIDGE
 
BO_ 110 MASTER_HEARTBEAT: 1 MASTER
 SG_ MASTER_hbt : 0|1@1+ (1,0) [0|1] "" SENSOR,MOTOR,BRIDGE,GPS
   
BO_ 111 SENSOR_HEARTBEAT: 1 SENSOR
 SG_ SENSOR_hbt : 0|1@1+ (1,0) [0|1] "" MASTER
  
BO_ 112 MOTOR_HEARTBEAT: 1 MOTOR
 SG_ MOTOR_hbt : 0|1@1+ (1,0) [0|1] "" MASTER
       
BO_ 113 GPS_HEARTBEAT: 1 GPS
 SG_ GPS_hbt : 0|1@1+ (1,0) [0|1] "" MASTER
    
BO_ 114 BRIDGE_HEARTBEAT: 1 BRIDGE
 SG_ BRIDGE_hbt : 0|1@1+ (1,0) [0|1] "" MASTER

BO_ 115 SENSOR_DEBUG: 1 SENSOR
 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_CAN_TX : 2|1@1+ (1,0) [0|0] "" DBG
 SG_ IO_DEBUG_bus_off : 3|1@1+ (1,0) [0|0] "" DBG
 
BO_ 116 MOTOR_DEBUG: 2 MOTOR
 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_RPM_kph : 2|12@1+ (0.01,0) [0.00|20.00] "kph" DBG
 
BO_ 117 MASTER_DEBUG: 1 MASTER
 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_drive_mode : 2|1@1+ (1,0) [0|0] "" DBG
 SG_ IO_DEBUG_HBT_FROM_ALL_CONTR : 3|1@1+ (1,0) [0|0] "" DBG

BO_ 118 GPS_DEBUG: 1 GPS
 SG_ IO_DEBUG_CAN_init : 0|1@1+ (1,0) [0|0] "" DBG
 SG_ IO_DEBUG_HBT_Transmit : 1|1@1+ (1,0) [0|0] "" DBG
 SG_ IO_DEBUG_bus_off : 2|1@1+ (1,0) [0|0] "" DBG
 SG_ IO_DEBUG_GPS_rx : 3|1@1+ (1,0) [0|0] "" DBG
 SG_ IO_DEBUG_GPS_Fix : 4|1@1+ (1,0) [0|0] "" DBG
 SG_ IO_DEBUG_Compass_Rx : 5|1@1+ (1,0) [0|0] "" DBG

BO_ 119 BRIDGE_DEBUG: 1 BRIDGE
 SG_ IO_DEBUG_CAN_init : 0|1@1+ (1,0) [0|0] "" DBG
 SG_ IO_DEBUG_HBT_Transmit : 1|1@1+ (1,0) [0|0] "" DBG
 SG_ IO_DEBUG_bus_off : 2|1@1+ (1,0) [0|0] "" DBG
 SG_ IO_DEBUG_Connected : 3|1@1+ (1,0) [0|0] "" DBG
 SG_ IO_DEBUG_Bridge_rx : 4|1@1+ (1,0) [0|0] "" DBG 

CM_ BU_ MASTER "The master controller driving the car";
CM_ BU_ MOTOR "The motor controller of the car";
CM_ BU_ SENSOR "The sensor controller of the car";
CM_ BU_ BRIDGE "The bridge controller of the car";
CM_ BU_ GPS "The gps controller of the car";
CM_ BU_ DBG "The debug node of the car";
CM_ BO_ 100 "Sync message used to synchronize the controllers";

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_ 103 100;
BA_ "GenMsgCycleTime" BO_ 104 100;
BA_ "GenMsgCycleTime" BO_ 105 100;
BA_ "GenMsgCycleTime" BO_ 106 100;
BA_ "GenMsgCycleTime" BO_ 107 100;
BA_ "GenMsgCycleTime" BO_ 108 100;
BA_ "GenMsgCycleTime" BO_ 109 100;
BA_ "GenMsgCycleTime" BO_ 110 100;
BA_ "GenMsgCycleTime" BO_ 111 100;
BA_ "GenMsgCycleTime" BO_ 112 100;
BA_ "GenMsgCycleTime" BO_ 113 100;
BA_ "GenMsgCycleTime" BO_ 114 100;
BA_ "GenMsgCycleTime" BO_ 115 100;
BA_ "GenMsgCycleTime" BO_ 116 100;
BA_ "GenMsgCycleTime" BO_ 117 100;
BA_ "FieldType" SG_ 104 MOTOR_DRIVE_cmd "MOTOR_DRIVE_cmd";


VAL_ 104 MOTOR_DRIVE_cmd 2 "MOTOR_STOP" 1 "MOTOR_REV" 0 "MOTOR_FORWARD" ;


A screenshot of the Bus Master Application is as shown below:

Busmaster.jpg


3D printing models

We used a 3D mount model to mount the ultrasonic sensor and compass. After testing the ultrasonic sensor at different angles we noticed that best results are when sensors are mounted at 70 degrees with respect to the ground. Most important thing to consider was the mount should be able to adjust tilt of the sensors since we were receiving lot of reflection from the ground. So in order to satisfy that requirement mount is constructed from two parts, the stand and part that holds the sensor what gave us freedom to test sensors positioning. We used the 3D mount design from Thingiverse.

Since we needed to keep the Compass sensor away from DC Motor's interference, we decided to keep the compass at certain height above the PCB. So we used 3D printing to print the support plate with the mounting holes of same dimension as M3X10 screw standoffs.

Ultrasonic Sensor Mount
Actual Mount


Compass Mount

Sensor Node

We used 2 sensor modules to achieve accurate and reliable obstacle avoidance system.
1. Lidar - Main controller to detect obstacle. Giving 360-degree view with a range up to 6 meters in distance.

  • RPLidar works on a mechanism known as laser triangulation ranging principle. The system measures distance data in more than 2000 times’ per second and with high-resolution distance output. RPLIDAR emits modulated infrared laser signal and the laser signal is then reflected by the object to be detected. The returning signal is sampled by vision acquisition system in RPLIDAR A1 and the DSP embedded in RPLIDAR starts processing the sample data and output distance value and angle value between object and RPLIDAR A1 through the communication interface.
Lidar Working Schematic

2. Ultrasonic Sensor (Maxbotix LV-MaxSonar-EZ0) - One Ultrasonic sensor with a maximum range of 600 cm was used to detect very small objects at the front that Lidar might miss because of it's leveled placement.

ultrasonic beam
  • Ultrasonic sensor uses a high-frequency beam to detect an object. It first throws light and reads the time taken for light to receive back, depending on the time calculated, it identifies the obstacle. It calibrates after it's first to read cycle, then it can continuously read data of light. The beam depending on the range is shown in figure.

Sensor Node Code

GitLab link to Sensor Code

Hardware Design

  • The Lidar is communicating with SJOne board through UART, we have used UART 2 here as shown in Pin config below.
  • Ultrasonic Sensor is simple Interrupt based, hence it connected through GPIO pins of SJOne board as shown in diagram.
Sensor Pin connection
  • Figure shows the usage of 4 LEDS and LCD display to notify us the position of obstacle.
LED indication
LCD screen showing the value of track of obstacle at respective direction

Implementation

Ultrasonic

LV Maxsonar ultrasonic sensor is used at the very front of the RC car to provide wide range sonar detection ranging from 0 to 645 cm. It supports LiDAR sensor to detect very small obstacles like stone that can hinder car from moving forward. so we have purposefully mounted it at a lower level than LiDAR.

LiDAR

RPLidar works on UART. We have used UART 2 of SJOne Board to establish communication between them.

  • Figure shows the several operation provided by RPLidar for better performance and reliable data.
Various Operations of RPLidar

Algorithm to establish communication through UART

  • In order to start the scanning of Lidar, first send the 0X20 via uart2.putchar(0x20). Before that, we can check the health status of RPLidar by sending 0x52. It waits for some time (timeout = 500ms), and if return status is not true throws error indicating Lidar is not initialized properly and hence it gets reset.
  • As soon as correct scan command is received by Lidar, it starts sending data frames continuously on UART. The frame consists of 5 bytes including the start bit, Angle, quality and distance, which are useful to identify the exact position of obstacle.
RPLidar data frame.png
  • This data is processed and divided into tracks of 25 cm each.
  • By looking at the track, we choose the sector value which depends on angle detected. Below figure shows the division of angle for respective sector value.
Figure shows the division of angles
  • The obstacle information is sent to Master Node through CAN.

Software Design

Ultrasonic

  • It works with the help of interrupt.
  • After configuring GPIO pins as RX and TX, set RX pin high.
  • PW pin gets the input, identify the type of interrupt
    • Rising edge interrupt.
    • Falling edge interrupt
  • Calculate distance to obstacle,
    • ultrasonic_data.distance = (stop_time - start_time)/147;

LiDAR

Below diagram shows the code flow of sensor module. A separate task was used to send sensor data over CAN, which continuously sends data in while(1) loop.

Sensor Flowchart

CAN DBC Messages Send from Sensor

  BO_ 105 SENSOR_NODE: 5 SENSOR
   SG_ SENSOR_FRONT_cm : 0|10@1+ (1,0) [0|645] "cm" MASTER,MOTOR,BRIDGE
   SG_ LIDAR_Obstacle_FRONT : 10|3@1+ (1,0) [0|0] "" MASTER,MOTOR,BRIDGE
   SG_ LIDAR_Obstacle_RIGHT : 13|3@1+ (1,0) [0|0] "" MASTER,MOTOR,BRIDGE
   SG_ LIDAR_Obstacle_LEFT : 16|3@1+ (1,0) [0|0] "" MASTER,MOTOR,BRIDGE
   SG_ LIDAR_Obstacle_BACK : 19|3@1+ (1,0) [0|0] "" MASTER,MOTOR,BRIDGE
   SG_ LIDAR_Obstacle_BACK_RIGHT : 22|3@1+ (1,0) [0|0] "" MASTER,MOTOR,BRIDGE
   SG_ LIDAR_Obstacle_BACK_LEFT : 25|3@1+ (1,0) [0|0] "" MASTER,MOTOR,BRIDGE

LED Blinking signals for SENSOR CONTROLLER ON CAR

* RED LED ON: MASTER HEARTBEAT STATUS on CAR
* BLUE LED ON: Obstacle detected at front of CAR
* Rightmost GREEN LED ON: Obstacle detected at right of CAR
* YELLOW LED ON: Obstacle detected at back of CAR
* Leftmost GREEN LED ON: Obstacle detected at left of CAR.

Technical Challenges

Ultrasonic

  • When mounted initially on CAR, ultrasonic was giving sometimes faulty readings as it was detecting ground as and obstacle.
    • We designed a 3D mount for it and adjusted it on such a angle that it gives perfect readings.
  • Initialization issue: Sometimes on power-up we noticed that Ultrasonic sensor was giving faulty readings(it was getting stuck on some fixed value).
    • After reading the datasheet accurately, I found that it calibrates itself during the first read cycle and so the obstacle should be at least 14 inches far from the sensor.
  • Ultrasonic Failure - When the CAR got crashed, Ultrasonic sensor failed and started giving incorrect data.
    • We replaced it's wired to get it working.

LiDAR

  • Identifying obstacle data and separating it.
    • Initially I lost a lot of time in figuring out the data frame as it consists of quality, angle, distance and start bit.
    • Dividing the frame bits appropriately and storing it separately in struct variables resolved the issue. Also after that depending on the angle, every 360 times data was fetched in a loop to cover each and every angle value.
  • Task overrun because of receiving a large number of data continuously over UART.
    • Used a separate task, that receives data continuously in a loop, i.e while(1).
    • Instead of receiving whole data in a single frame, took data character by character in a for loop 360 times, to get the value of obstacle at each degree.
  • Angle detection problem - When large angles were taken, for example, 30 degrees on the right, it was detecting nearer objects correctly but far objects were getting detected in some other range (for example in front instead of right) of angle because of angle spread. I divided the range into 10 degrees each and store it in the same variable to send it over CAN.
    For example, to get 30 degrees in right, 0-10,10-20 & 20-30 values are taken.
  • Received variable initialization problem.
    • I didn't initialize the character variable to get data from UART to 0 and hence it was taking garbage value.
      Thanks to Preet, at time of my code review he pointed out this problem and later I checked it with Unit Testing.
  • Some bugs here and there in the code.
    • I identified and resolved a few bugs after Unit testing the code.
  • Delay in sending data because of large CAN buffer size.
    • We were facing this issue with master, motor and sensor communication. The response time was slow as data was getting accumulated before sending because of large buffer size taken.


Motor Controller

Motor Controller is responsible to control the DC and Servo Motor, RPM Sensor measurements and LCD control. The motor control logic controls the steering and the speed of the vehicle using a servo and DC motor respectively based on the CAR_CONTROL_t CAN message from the master. It takes input from RPM sensor as a feedback for maintaining a constant speed and based on the RPM sensor reading, a PID loop calculates duty-cycle for PWM signal which are then given to DC motor. Based on other can messages from the sensor controller, geo controller and bridge controller, motor controller processes and communicates the information to the LCD by refreshing the data periodically in 10Hz function.

Hardware Design

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

RPM Sensor, DC and Servo Motor Hardware Interfacing
LCD Hardware Connections





Hardware Interface

Electronic Speed Controller (ESC)

We made use of the Traxxas ESC XL-05 which comes with the RC car. ESC stands for Electronic Speed Control. It is used to control the DC motor using PWM signals from the controller. It powers up when we connect a LiPo or NiMH battery of 7.4v. The ESC has a dc-to-dc converter which converts 7.4v to 6v and provides it to DC motor. It can provide high current to the power hungry DC motors running at faster speeds. It has an LED and a button which is used for calibration and setting different modes for the car.

Traxxas ESC XL5

DC Motor

Traxxas DC Motor

The DC motor is controlled using the ESC which get PWM pulses for controlling it. A PWM signal wire is connected to the microcontroller and the required current is provided by the LiPo battery and the ESC. Below table shows the LED functionality implemented in PCB for all the controllers.

LED DESIGNATION

GPIO PINS

DESCRIPTION

COLOR

  • D1
VCC and GND POWER RED
  • D2 MOTOR
P2.5 and VCC RPM RED
  • D3 MOTOR
P0.29 Motor Heartbeat Yellow
  • D4 MOTOR
P0.30 DC Motor Blue
  • D5 MOTOR
P1.19 Servo Motor Green
  • D6 BRIDGE
P0.29 Bridge Heartbeat Red
  • D7 BRIDGE
P0.30 DC Motor BLUE
  • D8 GPS
P0.30 Geographical FIX BLUE
  • D9 GPS
P0.29 Geographical Heartbeat Yellow
  • D10 GPS
P1.19 Compass Data Green
  • D11 SENSOR
P0.29 Sensor Heartbeat Green
  • D12 SENSOR
P0.30 Left Obstacle Yellow
  • D13 SENSOR
P1.19 Right Obstacle Blue
  • D14 SENSOR
P1.20 Front Obstacle Green
  • D15 SENSOR
P1.19 Right Obstacle Blue
  • D16 MASTER
P0.29 Sensor Heartbeat Red
  • D17 MASTER
P0.30 Motor Heartbeat Green
  • D18 MASTER
P1.19 Bridge Heartbeat Yellow
  • D19 MASTER
P1.20 Geographical Heartbeat Blue
DC Motor Pin Connection
S.No Wires - DC Motor Description
1. Positive Wire (already Connected) Positive Terminal
2. Negative Wire (already Connected) Negative terminal

The DC motor is controlled using PWM at 100Hz.

DC MOTOR Configuration
Operation Pulse Width Range(ms) Duty-cycle(%)
FORWARD 1.51 - 2.00 15.1 - 20.0
STOP 1.50 15.0
REVERSE 1.00 - 1.49 10.0 - 14.9


NOTE: Before using the Traxxas ESC to give PWM signal to DC motor calibrate it by going to this website:

https://traxxas.com/support/Programming-Your-Traxxas-Electronic-Speed-Control
The ESC must be given a pulse of 1.5ms when we turn it on or else the DC motor won't respond to PWM pulses.
Step 1: Give 2.00ms on-time pulses when LED blinks red once.
Step 2: Give 1.50ms on-time pulses when LED blinks red twice.
Step 3: Give 1.00ms on-time pulses and the LED color changes from red to green showing that the calibration was successful.

Servo Motor

Traxxas Servo Motor

The direction the vehicle's front wheels turn is dependent on the servo motor in the vehicle. Based on various PWM signals, the servo steers the front wheels of the vehicle in the left and right direction. The servo has 3 wires of which one is for the PWM input signal whereas the other two are to power up the servo. We powered our servo motor using the 6v power supply from the battery elimination circuit present in the ESC so that a single switch to turn on and off both the servo and DC motor. PWM signals to control the servo is provided by the motor controller. Based on the PWM signal from the SJOne board, the shaft shall be rotated to a certain degree left or right

Servo Motor Pin Connection
S.No Wires - Servo Motor Function
1. PWM connected to P2.1 PWM signal from SJOne board
2. VCC 6V power supply from ESC
3. Ground Common ground to system

RPM Sensor

Traxxas Speed Sensor

RPM sensor is used as a feedback element in the PID to maintain a constant speed of the vehicle. The RPM sensor mounts on the rear DC motor shaft compartment with a special assembly also provided by Traxxas. We make use of one magnet and we get one pulse on one wheel rotation The sensor works on the hall effect principle where it provides a current across its terminal when placed in a magnet's field. These pulses are read by the SJOne board and fed to the speed control algorithm. The RPM sensor has 3 wires, the white where are the output wire that provides the pulses to the SJone board and the other wires power the sensor.

Implementation

1. The idea is that every time the motor completes 1 whole revolution, it reaches very close to the sensor. And when the sensor detects the magnet nearby, it sends out a high pulse until the magnet moves away from it. Therefore, upon detecting the X number of a rising edge in Y seconds we can say that rpm was X revolutions/Y seconds.
2. During our initial testing of RPM Sensor with SJOne board, we saw that regardless of whether we bring the magnet close to the sensor or not, the signal voltage was always high. After some trail and errors, we found out that the signal pin(white wire) had to be connected to the VCC(red wire) across a 1K resistor which can act as weak pull down when it detects the magnet.

Speed Sensor Pin Connection
S.No Wires - RPM Sensor Function
1. Signal wire connected to P2.5 GPIO that supplies pulses to controller
2. VCC 6V power supply from ESC
3. GND Common ground


uLCD32-PTU

uLCD32-PTU by 4D systems has a 3.2" TFT LCD Display module. The module comes with a display resolution of 240x320 pixels. 4D Systems provides a programming cable based on UART for burning the LCD code to the module. The project is burnt to a uSD card which is used for display during booting of the LCD. It is recommended that we use the programming adapter provided by 4D systems as it has a special reset button that can be used to download the built project to the LCD display.Once the LCD display was configured with different widgets and screens, the motor module was coded to display information in LCD through UART. Workshop4 IDE was used to program the GUI, and data was transmitted from the SJOne board through UART communication. The LCD displays the main menu screen with options of all the modules: Sensor, Motor, Bridge, GPS, Compass and MIA information.

These modules represent the page numbers of the display whose information can be found from the pre-processed data format of the LCD.This data format contains the following fields:

  • The write command
  • Type of the object
  • Object ID
  • MSB and LSB values to be displayed in the LED.
  • The last pair of hex value is for checksum.

The following figure shows the programming cable and the pins used for uLCD32-PTU.

LCD connections


LCD Pin Connection
S.No Wires - LCD interface Function
1. TX Data Transmission connected to UART RX of SJ1 board
2. RX Data Reception connected to UART TX of SJ1 board
2. VCC Input 5v supply
3. GND Common ground
4. RES Reset Pulse(Not Required for our project)

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.

PWM *motor_control;     //pointer object defined globally
PWM *servo_control;
void init_pwm(long unsigned int freq) {
    motor_control = new PWM(PWM::pwm1, freq);      // using PWM constructor to initialize the PWM 2.0 pin to desired frequency
    servo_control = new PWM(PWM::pwm2, freq);
}

DC Motor

The DC motor is connected to pin P2.0 on SJONE board. The DC motor is commanded every 100ms to change or maintain its speed or direction(FORWARD, REVERSE and STOP). A switch case is used to check the command that we are receiving over CAN bus from master.

Pseudo code for dc motor and speed control

float speed = get_speed();
float _error = calculate_error_PID(drive_forward->MOTOR_mps, speed, &dc_motor);
*PWM_percent += _error
set_pwm_value(motor_1, *PWM_percent);

Servo Motor

The Servo motor is connected to pin P2.1 on SJONE board. The servo motor is commanded every 10ms to change or maintain its angle between 0 and 180 degrees. We receive angle in the range of -90(full left), 0(neutral) and +90(full right) from master. The calculate PWM_duty_cycle_servo function maps the angle received from master to PWM signal and rotates the servo motor accordingly.

Pseudo code for servo motor and angle calculation

on_time = 10 + ((servo->MOTOR_STEER_cmd + 90) * (10/180));
set_pwm_value(servo_2, on_time);

RPM Sensor

The RPM sensor is connected to pin P2.6 of SJONE board. When the wheel rotates once we get one pulse. We make use of interrupt to register these pulses in a 400ms time frame and then calculate the speed in m/s based on the formula:

speed_m_per_sec = (circumference * rotation_per_sec) / (constant);

After every 400ms we reset the pulse counter. We have an ISR which increments these pulses.

void eint3_handler(void){
    pulse++;
}

LED Blinking signals for MOTOR CONTROLLER

  • RED LED ON: MASTER HEARTBEAT STATUS on CAR
  • BLUE LED ON: Car is moving in reverse direction
  • YELLOW LED ON: Car is stopped
  • GREEN LED ON: Car is moving in forward direction

LCD Software Flow Chart

LCD Software Flowchart: 1Hz Task

Programming SJONE Board for LCD Display

  • As raw data often cannot be displayed on the LCD directly, the values to be displayed had to be converted to appropriate byte-sized values.
  • Communication with SJOne board was established at the baud rate of 115200 bps.
  • Commands for writing data and reading acknowledgment for various gauges were coded in the SJ1 board.

Creating a project using Workshop 4 IDE and programming the LCD display

  • After finalizing the design of the LCD's layout, a genie project was created using Workshop 4.
  • The layout was split into different forms (pages) and appropriate buttons and gauges were added for display.
  • uLCD-32PTU was programmed with the help of programming cable provided by 4D systems.

The steps taken for interfacing the LCD display with the SJONE board is shown on the right:

Each of the reading is considered as a object with the object type ID and object number. Below are the list of objects used for lcd.

#define GPS_DEST_LATITUDE_OBJ        0
#define GPS_DEST_LONGITUDE_OBJ       1
#define GPS_CURRENT_LATITUDE_OBJ     2
#define GPS_CURRENT_LONGITUDE_OBJ    3
#define GPS_HEADING_OBJ              13
#define GPS_BEARING_OBJ              14
#define GPS_DISTANCE_OBJ             3
#define MOTOR_SPEED_MS_OBJ           8
#define MOTOR_PWM_OBJ                12
#define MOTOR_RPM_OBJ                4
#define MOTOR_TURNING_ANGLE_OBJ      9
#define MOTOR_DISTANCE_COVERED_OBJ   10
#define MOTOR_DISTANCE_LEFT_OBJ      11

So our approach was to send a LCDquery at 1Hz task using the below function.

void lcd_screen_query(void)
{
   char comm[] = {0, 0x0a, 0, 0x0a};
   for (int i = 0; i < (int)sizeof(comm); i++)
   {
       uart3_put_char(comm[i], 0);
   }
}

This query sends a a array of character to LCD and LCD acknowledges it and sends the pre-formated data to the controller using lcd_receive() called at every 10Hz. The receive() will contain the page number(lcd_screen) based on the screen it is currently into and prints the data corresponding to that screen i.e. GPS screen will call GPS_print function to print the GPS values.

void lcd_print()
{
   switch (lcd_screen)
   {
       case menu:
           lcd_print_menu_screen();
           break;
       case bridge:
           lcd_print_bridge_screen();
           break;
       case gps:
           lcd_print_gps_screen();
           break;
       case sensor:
           lcd_print_sensor_screen();
           break;
       case motor:
           lcd_print_motor_screen();
           break;
       case home:
           lcd_print_home_screen();
           break;
       case mia:
           lcd_print_mia_screen();
           break;
       case compass:
           lcd_print_compass_screen();
           break;
       default:
           break;
   }
}

LCD Screens

Main Screen
Module Selection Screen
MOTOR Screen
Sensors Screen


MID Status Screen
GPS Screen
Compass Screen
Bluetooth Screen


Flow charts

DC motor control.jpg
Servo motor control.jpeg
Speed calc.jpg



DC motor speed and direction control using RPM sensor, Servo motor control and Speed calculator flow-chart

Technical Challenges

PWM frequency setting problem

The PWM frequency won't set if we were making use of global objects directly using the SJONE PWM drivers. We verified using logic analyzer that our frequency was getting set to 1.19KHz instead of 100Hz.
PWM motor_control(PWM::pwm1, freq);
PWM servo_control(PWM::pwm2, freq);
Solution: After trying out many things we made use of global pointer objects to solve the problem.
PWM *motor_control;     //pointer object defined globally
PWM *servo_control;
void init_pwm(long unsigned int freq) {
    motor_control = new PWM(PWM::pwm1, freq);      // using PWM constructor to initialize the PWM 2.0 pin to desired frequency
    servo_control = new PWM(PWM::pwm2, freq);
} 

DC motor shooting randomly

When we were testing our DC motor, we found that our dc motor would shoot randomly in forward and reverse direction when using GPP board. We checked our code and the entire wiring but were not able to fix it.
Solution: When our PCB arrived we tested the DC motor on it and it worked fine. One suggestion would be to use the PCB as soon as possible as it won't waste your time on debugging unnecessary problems.

PID Calibration for uphill and downhill

It uses an extensive amount of time to get the PID loop working which gives proper error values which maneuvers the car without stopping on uphill and controls speed during the downhill.
Solution:You should start using PID for maneuvering uphill and downhill conditions from the beginning.

LCD Refreshing

During testing the data received in LCD, we noticed that LCD was not getting refreshed quickly i.e even though PCAN dongle was updating data quickly but LCD was showing the data after a few seconds. At one point, the LCD stopped updating data.
Solution:We used snprintf() for GPS and Sensor values.For Compass and Motor, we implemented MSB and LSB approach where lower 8 bits of data(int) was stored in LSB and upper 8 bits in MSB, followed by our custom display function lcd_put_comm() which converted the data to the pre-formatted data and displayed data over UART using uart_put_char(). Below is an example
   char msb,lsb = 0;
   int local_heading = gps_bearing * 100;
   lsb = (char)((char) local_heading & 0xff);
   msb = (char)((char) (local_heading >> 8) & 0xff);
   lcd_put_comm(WRITE_OBJ, LED_DIGITS, GPS_HEADING_OBJ, msb, lsb);


Geographical Controller

Geographical Controller is one the most important controller in the autonomous car which helps it to navigate to its destination. This modules continuously update the position and orientation of the car with respect to geographical north and send the data to Master, Motor and Android controller boards. We are using the Adafruit Ultimate GPS module and CMPS11.

  • GEO CONTROLLER Git Link: [1]

Hardware Design

The hardware interface details of GPS and Compass Module with SJOne board are given below:

GPS & CMPS11 Module Hardware Interfacing


  • LED Blinking signals for GEO CONTROLLER ON CAR
* RED LED ON: MASTER HEARTBEAT STATUS on CAR
* BLUE LED ON: Shows GPS FIX STATUS on CAR
* GREEN LED ON: COMPASS Data Indication

GPS

  • GPS PinOut
* VCC: 3.3V Power 
* GND: Ground 
* TXD: Serial Transmit pin connected to RXD2 of SJOne board
* RXD: Serial Receive  pin connected to TXD2 of SJOne board 
* FIX: States if GPS is fixed not
GPRMC NMEA DATA


GPS is a global navigation satellite system that provides geolocation and time information to a GPS receiver anywhere on or near the Earth where there is an unobstructed line of sight to four or more GPS satellites.

The GPS module used in this project runs on UART communication protocol. Its default baud rate is 9600bps and we are working on the same baud rate to extract GPS data. The GPS module works on NMEA 0183 standards which define the electrical and data specification for communication between the GPS module and its controller. We are using the Recommended minimum specific GPS/Transit data (GPRMC) command. It provides us with three important data which are Fix, Latitude, and Longitude, required for localization and navigation of the car. The update rate of these data from the GPS module is configured at 10Hz and 5Hz for fix control status.

  • GPS Configurations:

GPS configuration Settings that we have used for the Adafruit GPS module is shown in the following picture. As per Arduino data-sheet, we can use different commands setting to set the different update rate from once a second (1 Hz) to 10 times a second (10 Hz) as per user requirements.

GPS Configuration Settings

Compass

  • Compass PinOut
* VCC: 3.3V Power 
* GND: Ground 
* SCL: Serial Clock pin connected to SCL of SJOne board
* SDA: Serial DATA pin connected to SDA of SJOne board

A Compass is an instrument used for navigation and orientation that shows direction relative to the geographic cardinal directions (or points). Compass is communicating over I2C with SJ One board. The register 2 and 3 of the compass provide the compass bearing angle (0- 360 range). Calibrating the compass is an important part. We are calibrating it on ‘horizontal calibration mode’, it works for us because the compass has tilt calibration.

We are using the compass in I2C mode of operation. The following table on the left shows the registers and their functions and the software flow chart for getting/setting compass data and calibration on demand and We are using the Compass bearing (16-bit) given by the compass registers 2 and 3 to calculate our car heading.

Registers of CMPS11
Registers of CMPS11


Software Design & Implementation

The Geographical Controller is in place for navigation purpose. It has two essential parts, namely GPS and compass. It provides direction to the car, by calculating the heading angle and the distance between the coordinates, based on GPS and compass readings. To calculate the heading angle, we need a compass bearing angle and angle between the line joining the two coordinates and the true north(bearing angle for GPS).


Hard Power ON Flow Chart


SFMC for 1HZ
SFMC for 10Hz


Distance between the two coordinates calculation

The distance between the two coordinates can be calculated using the Haversine formula.

 a = sin²(Δφ/2) + cos φ1 ⋅ cos φ2 ⋅ sin²(Δλ/2)
 c = 2 ⋅ atan2(√a, √(1−a))
 d = R ⋅ c
 where,
       φ1 = Latitude of 1st Coordinate
       φ2 = Latitude of 2nd Coordinate
       λ1 = Longitude of 1st Coordinate
       λ2 = Longitude of 2nd Coordinate
       Δφ = φ2 - φ1
       Δλ = λ2 - λ1
       d  = distance between the two coordinates
       R  = earth’s radius (mean radius = 6,371km)
 Note: All the angles should be in radians.

GPS Heading angle calculation

Bearing angle calculation

With reference to the figure, the Heading angle for GPS is the angle between the line joining the two coordinates and the true north. To calculate it graphically, draw a vector pointing towards the destination coordinates from the start point coordinate and measure the angle between the vector and the true north. Use the below formula to calculate the angle mathematically.

 Heading angle(α) = atan2(sin Δλ ⋅ cos φ2 , cos φ1 ⋅ sin φ2 − sin φ1 ⋅ cos φ2 ⋅ cos Δλ)
 where,
       φ1 = Latitude of 1st Coordinate
       φ2 = Latitude of 2nd Coordinate
       λ1 = Longitude of 1st Coordinate
       λ2 = Longitude of 2nd Coordinate
       Δλ = λ2 - λ1

GPS Checkpoint Navigation

The car reads the value of current coordinates from the GPS module to determine its Euclidean distance from the first checkpoint. It also checks the value on the compass to know which direction it should preferably move in i.e. Heading angle. The sensor readings help it ascertain that there isn't an obstacle to hinder its movement in the determined direction.

We have selected 23 checkpoints on the location where the demo is going to takes place and we have filled these coordinates in a Checkpoint Array as shown below.

Selected Checkpoints
Checkpoints Array


  • The Car begins navigating its way from its current location to the final destination using enlisted checkpoints. When the car arrives at a first checkpoint, then GEO Controller will look into its GPS checkpoints constant array to look for next nearest checkpoint.
  • While selecting Checkpoint we are using Linear Searching technique to select next checkpoint which is closer to the current location and as well as closer to the final destination.

The Software state machine flow chart for GPS Navigation is shown below:

GPS Checkpoint Navigation

Technical Challenges

  • Issues 1 - GPS doesn’t retain configuration settings; GPS module was forgetting its baud setting of 57600bps configuration settings after a long run testing of GPS module(we kept GPS for overnight testing to capture logs of GPRMC to check its location consistency) before the implementation of Distance calculation so after 4-5 hours its start giving Null values for latitude and longitude after reviewing the logs of the data captured that was giving garbage data as UART baud mismatching gives then it has to be configured again that means baud rate setting using PMTK command.
 Solution - As per recommendation is given in Arduino Data sheet we should use default baud settings of 9600 later we never faced this issue and it was giving a good fix.
  • Issue 2 - One of the most important thing with GPS is to get a quick fix. Our First Time to fix was coming approx 50seconds even in the open sky which is not good for self-driving car the moment engine of the car turns on we should have Coordinates of the car to navigate this to the destination location. So first Time to fix was one the hurdle for us.
 Solution - We have followed one of the Arduino Forum in which one of the experts give few tips on how to improve this GPS Fix issue and one of the tips worked for us was the of the Cell battery with the voltage of more than 2.89v. This resolves GPS fix the issue for us. 
  • Issue 3 - Compass frequently losing its calibration when we were using CMPS11 in calibrated Mode.
 Solution - Using CMPS11 in default calibration mode helped us to get rid of this problem
  • Issue 4 Ahhhh!! Faced task overrun issue with GPS NMEA data. When we were using NMEA parsing and shortest path algorithm in one task or even in two different tasks code was crashing like anything. However, NMEA parsing and Path Finding algorithm were working fine.
 Solution - Preet's easy parsing function(using sscanf) and his advice of using separate task using FreeRTOS helped us resolving this problem.
  • Issue 5 During parsing of GPS Coordinates we have faced one issue with data type Float. Due to can transmission, we were using float data type for Latitude and longitude and what we have noticed that after getting data in string/char* and converting it to float then last two-three decimal places of latitude and longitude were changing frequently due to which Calculated distance from SOurce to destination was changing randomly even car is sitting at one location.
 Solution - GPS coordinates require double datatype so, we took coordinates as double and then while sending data on CAN we were typecasting that to float. As we were doing all calculation related to coordinates, distance and checkpoints calculations on GEO Controller itself. So after doing all the calculations in double, we were type casting data to float and we were sending that to MASTER & BRIDGE.



Bridge Controller Communication

Bridge Controller is used for communication between the SJOne board and the android phone using the HC-05 Bluetooth module. The main purpose of the bridge Controller is to receive the start/stop command and destination location from the Android app. Bridge controller will transmit all the sensor information and debug information and this information will be displayed on the android app.

  • BRIDGE CONTROLLER Git Link: [2]

Hardware Design

Bluetooth Module Hardware Interfacing:

We are using an HC-05 Bluetooth module to send and receive the data from our android application to Controller. The Bridge controller is connected to the Bluetooth module through the Serial interface(UART2) of SjOne board and we have configured HC-05 at 38400 baud rate 8-bit data and 1 stop bit using modules Communication Mode. Bridge Controller is connected to other SJOne Boards using CAN bus. The Bluetooth module communicates with the SJOne board using UART communication at 38400 baud rate.


HC-05 Module Hardware Interfacing


HC-05 Bluetooth module

HC-05 Bluetooth Module is used to set up wireless communication between the Car and the Android phone. This module is based on the Cambridge Silicon Radio BC417 2.4 GHz BlueTooth Radio chip. This is a complex chip which uses an external 8 Mbit flash memory It includes the Radio and Memory chips, 26 MHz crystal, antenna, and RF matching network. The right section of the Bluetooth Board has connection pins for power and signals as well as a 5V to 3.3V Regulator, LED, and level shifting.

  • HC-05 PinOut
* EN:  In a case brought HIGH before power is applied, forces AT Command Setup Mode 
* VCC: 5V Power 
* GND: Ground 
* TXD: Serial Transmit pin connected to RXD2 of SJOne board
* RXD: Serial Receive  pin connected to TXD2 of SJOne board 
* STATE: States if connected or not
  • LED Blinking signals
* Flashing RED Fast: Ready for Pairing with nearby Bluetooth device available
* Flashing RED Slow: Paired and Connected

Software Design

TasktableBle.png Flowchart-reception-1.jpeg BleTransmission.png

Technical Challenges

  • Android App was crashing due to the parsing function when there was no GPS data coming from the Bluetooth module. To solve this problem we added checks in the bridge controller to not to send GPS data if the GPS is not yet fixed.
  • Bridge controller's task was getting overrun when used snprint and printf in a task. (printf was just used for initial testing).Then after debugging, we found this problem and removed printf. snprintf and sprintf are working fine in 100Hz function.


Master Module

Hardware Design

Design and Implementation

  • As name suffice, Master Node acts as the brain of the RC car and gives controlled signals to every other module.
  • It manages the communication among all the modules, including Motor, Sensor, Geographical and Bridge Controller.
  • Master receives periodically data from CAN bus based on message ID of the sender module.
  • Below shows the connection of Master module on the CAN bus, connected with CAN Transceiver.
Master-CAN Interfcaing

Software Design

  • As the Master takes all the decisions, it has the highest priority and hence the lowest message Id on CAN DBC.
  • Figure illustrates the high-level bus flow from master to every module.
Master Control Flow

Implementation

Heartbeat Message of All Modules

  • As Master node handles all the communication from other modules, each node continuously sends its heartbeat to master, confirming that it is active and working properly.
  • If all the heartbeats are not received by the master, it sends STOP command to bridge so CAR doesn't run into a stage when any one of a node is not working. This mechanism provides us to eliminate running into an error state.
  • If the heartbeat is not received, Master handles this using MIA.
  • Code below displays heartbeat synchronization and MIA handling of all nodes.
  bool hbt_sync_from_all_node(void)
  {
    is_hbt_sync_flag = sensor_hbt_sync & motor_hbt_sync & gps_hbt_sync & bridge_hbt_sync;
    return is_hbt_sync_flag;
  }
  void master_mia_handler(void)
  {
    if (dbc_handle_mia_SENSOR_HEARTBEAT(&sensor_hbt, 25))
    {
       sensor_hbt_sync = false;
    }
    if (dbc_handle_mia_MOTOR_HEARTBEAT(&motor_hbt, 25))
    {
       motor_hbt_sync = false;
    }
    if (dbc_handle_mia_GPS_HEARTBEAT(&gps_hbt, 25))
    {
       gps_hbt_sync = false;
    }
    if (dbc_handle_mia_BRIDGE_HEARTBEAT(&bridge_hbt, 25))
    {
       bridge_hbt_sync = false;
    }
  }
Heartbeat LED of all nodes on Master

Testing and Technical Challenges

  • Delay in sending steer command to the motor.
    • Initially there was some delay observed while receiving the sensor obstacle information and sending relevant command to motor, because of this synchronization problem we were suffering from the delayed response.
    • After plenty of hardware and software debugging, we noticed the buffer size of CAN RX/TX was much larger than required. It was corrected on sensor and motor side as well.
  • Taking time in reversing even though the reverse command was send
    • Motor took time to reverse as it has to break it's PID loop.
    • The solution to this was to send a stop command(0), before sending the reverse command.

<Bullet or Headings of a module>

Improper Unit Testing

  • The problem of CAN buffer described above was detected by Unit Testing itself.
    • Along with that bug, I found few more bugs from unit testing the code.


Mobile Application

Software Design

1. Enable Bluetooth and Connect to bridge controller

Wireless communication with the car takes places with communication over Bluetooth protocol. Android Application is created which provides an interface to exchange data and configure the car parameters.

The android app connects to the HC-05 BLE module of the bridge controller. The Bluetooth ask the user for permission to access location and prompts to enable Bluetooth if it's already OFF. Our app is designed to connect to only TechSavy Bluetooth module and no other Bluetooth device to ease the setup of Bluetooth communication. A Bluetooth adapter connects to the HC-05 module and opens a Bluetooth Socket over which read and write messages are sent. A thread runs in the background which checks for available data, reads it and the data can then be processed. Data is written via the same Bluetooth socket. Refer to the following link to get started with Bluetooth on Android app and connection to HC-05 module ([3]).

2. Start/Stop Command and Log Sensor values

Start and Stop commands are sent to the RC car via the application. When Start/Stop button is pressed 1 or 0 commands are sent to the bridge controller when then transmits it to the CAN Bus for processing. Bluetooth status, Sensor Values, Motor parameters, GPS location, compass heading angle, distance to the checkpoint is displayed for debugging purpose. Sensor, GPS, motor Messages coming from CAN bus are decoded by the bridge controller and sent to the Android application as a string. The android app parses the string and categorizes the data to store it in appropriate variables. The data is then displayed as a text view in Bluetooth activity. To visit the Map Activity for setting destination and checkpoints a button is added. The map Activity opens on pressing the button.

The user is asked to enable Bluetooth
User should allow to enable Location
Connecting to the Tech Savy CAR
Connected to the module

3. Map Activity

The map activity is used in our app to show the current location of the car and set the destination marker which the car will navigate too. When map loads in the app the cars current location is indicated coming from the GPS as the source location (Red Marker). The desired location on the map can be set as the destination by long clicking on the map (Light Green marker). The destination can be changed as desired by long pressing again. When the start button is pressed command 1 is sent to the CAN bus via Bluetooth to start the car. A thread starts in the background to indicate the current position of the car when the car moves (light blue marker). Also, a polyline is drawn between the source and destination marker to indicate the direction in which the car will move. For adding Google map to app refer the following [4](Refer to Maps and geolocation section)

Map1.jpeg Car stop.jpeg

Testing and Technical Challenges

1. We faced the problem of adding Bluetooth functionality in the app. There is a lack of tutorials online which shows how to develop an android app with Bluetooth capability and communicating with the HC-05 module. Fortunately, we found this webpage [5] which helped us and Youtube videos of Coding with Mitch.

2. It was difficult to design the UI on the app with little java and Android experience. We designing UI from mainly two resources [6] [7]and searching online for problems faced by us.

3. Initially, we developed the app such that we had to manually connect to a paired device to use Bluetooth functionality. This gave us problems while sending commands to the bridge controller. We solved this problem by fixing the device connection only to our HC-05 module and adding only a single Bluetooth connection button on the app bar for Bluetooth connection.

4. When we received too many sensor values and debug messages from the bridge controller continuously, the app was crashing due to the input buffer overflow. We solved this problem by adding a 1000ms sleep time to limit the input data coming to the app.

5. There was a requirement to continuously update a marker on the map indicating the current location of the car for user feedback. We achieved this using a thread in the background which updated cars position every 1 second.


Suggestions for Future Students

  • For Master Controller
    • Don't make your obstacle avoidance complex by implementing reverse condition. Just keep your code simple.
    • One good approach a developer should follow is to unit test their own code. Would you buy a product which is suppose to be tested later?
    • Remember the KISS approach when you code. (Keep It Simple and Stupid).
    • For this controller, one should know the basics in C/ C++ and some good debugging skills. Because if you don't have one, you will eventually end up spending more time debugging your problem.
  • For Hardware Team
    • Order Hardware and Components as early as possible.
    • Select components wisely don't try to save money on this part of the project as bad quality hardware can't help you even with best software implementation.
    • Try to power up all modules using 6V coming from LiPo battery. Use IC boosters for converting 6V to 5V and 3.3V. This way there won't be a need of separate power bank and overall weight will be reduced.
    • While designing PCB keep the tracing width of power lines to 1 mm so that sufficient current can be pass through it.
    • PCB spacing should be 12-15 mil.
    • To reduce the magnetic interference from DC Motor, place the compass on the center or near the front side of the car at a height using standoffs.
    • Another alternative to standoffs could be implementing ground rings for compass and GPS Antenna which allows passing the EMI directly to the ground.
    • Get more samples of CAN transceiver IC's as it can get damaged easily.
  • For SENSOR Controller Team
    • LIDAR - It has some limitations when tests/demo takes place in bright sunlight. when direct light falls on it, so gives faulty readings.
    • LIDAR Consumes more power, hence need a separate power source for it due to which battery consumption of overall CAR is double as compared to the CAR use ultrasonic sensors for obstacle detection.
    • LIDAR is not even cost effective hence should use Ultrasonic instead we realized it very late.
    • Sensor Implementation doesn't need any averaging or complex algorithms.
  • For GEO Controller Team
    • Suggestions for GEO Controller software development is used FreeRTOS separate Tasks instead of using periodic tasks for NMEA receiving and parsing.
    • For GPS Checkpoint navigation use simple and stupid coding no need to implement Dijkstra and complex algorithms for short distance calculation on Geo Controller linear or binary searching technique is enough to implement it successfully.
    • For Compass use default calibration mode no need to add any checks and calibrations. Factory mode should be enough to get accurate results.
  • For Motor Controller Team
    • Use global pointers while using PWM drivers of SJONE board and set the frequency appropriately before testing it on motor(50Hz or 100Hz is fine).
    • Calibrate the ESC first for any RC car you purchase and get that right or the DC motor wont work.
    • Clear the CAN buffer periodically or the car might react to the commands with some delay.
  • Tips for getting GOOD Grades and to remain in top 3 teams
    • Select your team mates wisely, and make sure every one dedicates them self for this project.
    • Be an active member of your team and review rubrics every week before going to demonstrate your CAR.
    • As soon as the professor mentioned about the project please start working on the project right from the beginning otherwise at the end you have struggled with finals and you will be left with less time for testing and you have to struggle in demo.
    • Although you can get lots of information from seniors still don't take this project light this is a really interesting and challenging project.

Conclusion

Unit Testing Report Example

It was a really great working experience for all of us. We were really thrilled from the beginning that we will be working on something that is quite relevant in the industries these days. We worked as a team of eight which helped us all to know the importance of team-work and co-ordination. We learned many great stuff like

  • CAN bus:
    • Using this bus, we were able to communicate with five devices connected which each other.
    • Also, we learnt how to debug and interpret CAN message using BusMaster.
  • LIDAR and ultrasonic sensor:
    • At start we felt LIDAR would be easy to use because it gives us the obstacle data for all 360 degree. But as we started using it, we found out that keeping wider angle does not give us accurate data. Then we realised that at after certain distance the angles intersect with each other because of angle spread and we get the same reading for both angle zone. So we selected our angle zone precisely and accurately by doing some trials and error.
  • PCB designing:
    • We realised that using GPP for long term is not a good idea because every time our car crashed, there were some breakdown in the wires and our CAN bus stopped working. Initially we spent a lot of time debugging hardware and doing soldering.
    • So the hardware team started designing the PCB, and when our PCB was mounted on car, we spent hardly any time debugging the hardware.
  • We learnt about NMEA data packets while working with GPS and came to know how google map Application actaully works with the help of GPS satellites in view for navigation.
  • Unit testing : Unity and cmock framework are great tools for learning and it helped us to get great results in less amount of time. Unit testing of code is a must and should be adopted.
  • Git : We learnt all the basic of GIT and it plays an important to role for source code versioning.

There were a lot of problems while doing this project but it was a steep learning curve. In the end we were able to achieve our objective with really good results.

Project Video

Tech Savy Project Video

Project Source Code

  • Git Project Link: [8]

References

Acknowledgement

We would like to express our gratitude to Professor Preetpal Kang for generously sharing his time and knowledge with us and guiding us through the completion of this project. We would also like to thank the Pratap(ISA) for their valuable advice and constructive feedback.

References Used

LIDAR
PID Control
LCD
Android GUI
Google Maps
PCB Design using DipTrace

Datasheets

[1] XL-MaxSonar-EZ4 Ultrasonic Sensor
[2] 4D Systems LCD
[3] CAN Transceiver
[4] GPS Module
[5] Compass Module