Difference between revisions of "S19: Run D.B.C"

From Embedded Systems Learning Academy
Jump to: navigation, search
(Bill Of Materials)
(Technical Challenges)
Line 829: Line 829:
 
The primary technical challenge that we encountered, while developing the Bridge Controller, occurred during a demo. In an effort to display readings from sensor and geo on the Android application in real time, "CAN Receive" function was used, which in turn used a while loop to receive all CAN messages and then extract geo and sensor data, parse them and send them over UART to android application. Initially, we compiled all the data received and sent them within the CAN receive function which caused the app to crash/display junk values. To overcome this we replaced the while loop with if, however, this slowed down the rate at which messages were received and we displayed old data on App.
 
The primary technical challenge that we encountered, while developing the Bridge Controller, occurred during a demo. In an effort to display readings from sensor and geo on the Android application in real time, "CAN Receive" function was used, which in turn used a while loop to receive all CAN messages and then extract geo and sensor data, parse them and send them over UART to android application. Initially, we compiled all the data received and sent them within the CAN receive function which caused the app to crash/display junk values. To overcome this we replaced the while loop with if, however, this slowed down the rate at which messages were received and we displayed old data on App.
 
It took a while to figure out, but we created a new function called compile and send where we concatenated data and called it at 2Hz which fixed the issue.
 
It took a while to figure out, but we created a new function called compile and send where we concatenated data and called it at 2Hz which fixed the issue.
 +
 +
===== <font color="green"> '''''interfacing between bridge and geographic modules''''' </font> =====
 +
Another challenge we faced is the task of interfacing between geographic and bridge modules. Not long after starting the task, we realized that timing is very important. Since Dijkstra path-finding algorithm is only needed to run once, we need to make sure we obtain destination from Android phone first before running the algorithm. We also had to make sure geographic module receives the checkpoint from bridge module first before doing the bearing and distance calculations. We solved the first issue by setting a flag for Dijkstra algorithm. Every second the SJone board will check to see if the destination structure is populated. If it is, it sets a flag that enables the population of matrix needed by the algorithm and the algorithm itself is run shortly after. Latter issue by inputting a dummy distance of 1000m as the output of our distance calculation, before any checkpoint data arrives from bridge module. If a value of 1000 is showing on the LCD screen attached to the car, we know that geographic module has not yet gotten a checkpoint coordinate from bridge.
  
 
=== <font color="green"> Bill Of Materials </font> ===
 
=== <font color="green"> Bill Of Materials </font> ===

Revision as of 01:23, 23 May 2019

caption
caption

Contents

ABSTRACT

The RUN-D.B.C project, involves the design and construction of an autonomously navigating RC car. Development of the R.C car's subsystem modules will be divided amongst and performed by seven team members. Each team member will lead or significantly contribute to the development of at least one subsystem.

INTRODUCTION AND OBJECTIVES

RC CAR OBJECTIVES

  • Successfully detect and avoid obstacles
  • Autonomously navigate to a fixed destination, from a fixed starting location; based on feedback from a GPS
  • Integrate communication between the RC car's master controller and an Android device, using Bluetooth
  • Integrate system hardware communication using a PCB


TEAM OBJECTIVES

  • Strive to learn as much as possible, in order to develop a professional product
  • Establish and enforce professional software design standards
  • Establish and enforce professional hardware design standards
  • Achieve 100% code coverage, during unit testing
  • Carefully document and track all bugs encountered and patched, during development
  • Clearly communicate the development of all modules of the RC car


CORE MODULES OF RC CAR

  • Android Mobile Application
  • Bridge Controller
  • Geographic Controller
  • Master Controller
  • Motor Controller
  • Sensor Controller
  • Hardware Integration PCB
  • Wiring Harness


PROJECT MANAGEMENT ADMINISTRATION ROLES

  • Team Lead
  • Finance Manager
  • Git Repository Manager
  • Wiki Report Manager
  • Bill of Materials Manager


TEAM MEMBERS & RESPONSIBILITIES

Team Members

Administrative Roles

Technical Roles

  • Tristan French
  • Team Lead
  • Git Repository Manager
  • Finance Manager
  • Master Controller (Lead)
  • Hardware Integration PCB
  • Testing and Integration
  • Ryan Zelek
  • Motor Controller (Lead)
  • Testing and Integration
  • Master Controller
  • Samir Mohammed
  • Wiki Report Manager
  • Bill of Materials Manager
  • Android Mobile Application & Bridge Controller (Lead)
  • Hardware Integration PCB
  • Testing and Integration
  • Vignesh Kumar Venkateshwar
  • Android Mobile Application & Bridge Controller
  • Motor Controller
  • Testing and Integration
  • Bharath Vyas Balasubramanyam
  • Geographic Controller (Lead)
  • Motor Controller
  • Testing and Integration
  • Nuoya Xie
  • Sensor Controller (Lead)
  • Geographic Controller
  • Testing and Integration
  • Chong Hang Cheong
  • Sensor Controller
  • Geographic Controller
  • Testing and Integration


SCHEDULE

TEAM MEETING DATES & DELIVERABLES

Week#

Date Assigned

Deliverables

Status

1 2/16/19
  • Share team contact information
  • Create Git Repository (Tristan)
  • Set up Slack
  • Invite Preet to Slack
  • Establish Code Guidelines and Standards
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
2 2/24/19
  • (1/2 team) Share research of past projects
  • Establish ownership of Administrative and Technical Project Modules
  • Establish weekly team meeting time
  • Establish Team Slack usage Guidelines and Standards
  • Received CAN Transceivers
  • Create Git directory structure (Tristan)
  • Create a Bill of Materials (Samir)
  • Select and order an RC car (Bharath)
  • Push a file to Git Repository
  • Conduct research of project modules (based on ownership/sub-team)
  • Invite Preet to Gitlab
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
3 3/3/19
  • (2/2 team) Share research of past projects
  • Explore using Splitwise for managing project finances
  • Explore using Taiga.io for project management (Samir/Tristan)
  • Sub-teams share research and findings with each other and the team
  • Start planning what parts need to be ordered and update BoM
  • Research which PCB design tools we can use to develop a 4-layer PCB (EAGLE vs. KiCAD)
  • Email Preet regarding LCD screen for Bridge Controller
  • Interface with the HC05 Bluetooth module
  • Research frameworks for Android App development and decide which to use
  • Research GPS modules and decide which to use
  • Create a high-level system block diagram and control scheme
  • Develop a high-level plan interfacing with speed controller and servo controller
  • Test performance/specs of current Ultrasonic sensors and research others
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
4 3/10/19
  • Each team create a schedule for sub-system development and send to Samir
  • Set up Cygwin on Windows (and configure) Mac machines for auto-formatting
  • Finalize and purchase LCD screen for Bridge Controller
  • Learn to develop in Android Studio (watch tutorials and begin developing Android App)
  • Purchase Adafruit Ultimate GPS module
  • Purchase long-range distance sensors and select bump sensors
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
5 3/17/19
  • Establish Git Repository Structure (Tristan)
  • Select PCB manufacturer
  • Complete high-level system block diagram
  • Complete
  • Complete
  • Complete
6 3/24/19
  • Select Android mobile phone/OS to load and run Application
  • Interface with GPS and compass modules
  • Finalize high-level system block diagram and control scheme
  • Record how servo and DC motors react to RC Transmitter and Receiver feedback
  • Interface with with speed controller and servo controller
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
7 3/31/19
  • All parts have been ordered
  • Create button to launch mobile application
  • Integrate Google Maps into mobile application
  • Use feedback from GPS and compass to calculate bearing angle
  • LPC 1758 responds to feedback from motor speed sensor (reports RPM of wheels, when a PWM signal is applied)
  • Complete DBC CAN message format
  • Complete DBC CAN message format
  • LPC 1758 responds to feedback from bump sensor
  • LPC 1758 responds to feedback from Ultrasonic sensors (reports distance of objects in their detection radius)
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
8 4/7/19
  • Successfully get starting and destination coordinates
  • Transmit latitude and longitude coordinates as CAN messages to master controller
  • Master controller can send/receive CAN messages to/from all other controllers on CANbus
  • Complete sensor module code and push final revision to GitLab
  • Angle wheels left/right/straight based on CAN feedback from master controller
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
9 4/14/19
  • Send a message from the Android Mobile Application to the Bridge Controller
  • Transmit heading and bearing angle as CAN messages to master controller
  • Completed implementation of speed control algorithm
  • Implement obstacle avoidance algorithm
  • Mount and wire sensors to perfboard on car
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
10 4/21/19
  • Complete first indoor vehicle test drive
  • Plot CAN signals in Busmaster
  • Complete unit testing code for all modules
  • Implement debug messages
  • Review PCB Schematics for errors/inconsistencies
  • Push final schematics to Google Drive
  • Send starting/destination coordinates to bridge controller
  • Send starting/destination coordinates as CAN messages from bridge controller to geographic controller
  • Design a feed back mechanism to adjust speed of DC motor using RPM sensor values for vehicular movement on the slope
  • Mount and solder encoder perfboard
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
11 4/28/19
  • Achieve full CAN communication between all subsystems
  • Complete unit testing code for all subsystems
  • Complete PCB layout and send board to fabrication house
  • Order PCB and components (Tristan)
  • Launch a google map fragment on the Android Mobile Application
  • Input starting and destination latitude and longitude coordinates in Map
  • Develop a pathfinding scheme
  • Use GPS feedback to govern (motor behavior) car movement
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
12 5/5/19
  • Complete indoor test drive of car
  • Assemble/solder PCB
  • Integrate PCB into car
  • Confirm that PCB can supply adequate power to car
  • Integrate Google Maps into Android Mobile Application
  • Display sensor and compass data on Android Mobile Application
  • Transmit destination latitude and longitude coordinates from Android Mobile Application
  • Complete LCD integration with Master Controller
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
13 5/12/19
  • Send module summaries to Samir for Wiki report population
  • Complete outside test drive from start to destination
  • Complete
  • Complete
13 5/19/19
  • Complete Wiki Report (Samir)
  • Complete Individual Evaluations
  • Schedule time to test car outside on Monday (Samir, Nuoya, Tristan)
  • Complete final DBC file
  • Integrate pathfinding algorithm with bridge controller (Nuoya and Kelvin)
  • Complete
  • Complete
  • Complete
  • Complete
  • Complete
14 5/22/19
  • Push final code to GIT
  • DEMO
  • Finalize finances and decide who gets to keep the car...
  • Complete
  • Complete
  • Complete


BILL OF MATERIALS (GENERAL PARTS)

MICRO-CONTROLLERS

PART NAME

PART MODEL & SOURCE

QUANTITY

COST PER UNIT (USD)

  • Micro-controller
  • LPC 1758 (Purchased from Preet Kang)
  • 5
  • $80.00


RC CAR

PART NAME

PART MODEL & SOURCE

QUANTITY

COST PER UNIT (USD)

  • RC Car
  • 1
  • $205.99
  • Lithium-Ion Battery
  • 1
  • $74.95
  • Battery Charger
  • 1
  • $47.95


HARDWARE INTEGRATION PCB

Hardware Design

RUN DBC PCB layout.jpeg


The hardware integration PCB was designed with two goals:

1. Minimize the footprint of the onboard electronics
2. Minimize the chances of wires disconnecting, during drives

To accomplish these goals, all controllers were directly connected to the board's 34 pin header arrays, while all sensors were connected to the board, using ribbon cables and locking connectors. The master controller's header pins were inverted and then connected to a header array on top of the PCB, while the other controllers were mounted to the bottom. This guaranteed secure power and signal transmission paths, throughout the system.

The board consisted of 4 layers:

Signal
3.3V
5.0V
GND

Technical Challenges

Design

  • Balancing priorities between HW design and getting a working prototype
  • Finalizing a PCB design, when some components and module designs are not nailed down


Assembly

  • DB-9 connector for CAN dongle was wired backwards in the PCB design. Because there are several unused pins, we were able to just solder jumper wires to connect CAN HI and CAN LOW to the correct pins.
  • Spacing for headers with clips were not accounted for properly in the design. two of them are very close. It's a tight fit, but it should work.
  • Wireless antenna connector on master board not accounted for in footprint, it may have to be removed to avoid interference with one connector.

Bill Of Materials

HARDWARE INTEGRATION PCB

PART NAME

PART MODEL

QUANTITY

COST PER UNIT (USD)

  • CAN Transceiver
  • 5
  • $2.38
  • Buzzer
  • 2
  • $0.83
  • Buzzer Switch
  • 1
  • $0.15
  • 3.3V Regulator
  • 1
  • $0.46
  • 5V Regulator
  • 1
  • $2.36
  • Red LED
  • 1
  • $-.--
  • Diode
  • 1
  • $0.32
  • 100uF Capacitor
  • 1
  • $0.44
  • 10uF Capacitor
  • 1
  • $0.44
  • 4.7uF Capacitor
  • 1
  • $0.44
  • 1uF Capacitor
  • 1
  • $0.44
  • 10K Resistor
  • 1
  • $0.44
  • 5.1K Resistor
  • 1
  • $0.44
  • 1K Resistor
  • 1
  • $0.44


CAN NETWORK

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

Hardware Design

<Show your CAN bus hardware design>

DBC File

<Gitlab link to your DBC file> <You can optionally use an inline image>



ANDROID MOBILE APPLICATION

Software Design

Development of the Android Mobile Application happened in two phases. The first involved setting up bluetooth communication between the HC-05 and the Android mobile phone, while the second involved integrating Google Maps into the application. Both phases presented unique technical challenges that we had to address.

Bluetooth Integration

Maintaining a bluetooth connection between the Android phone and the HC-05 module, proved to be more arduous that we expected. Luckily, Google provided extensive resources to help with the process, on the Android developer website (this might be the best starting point for future CMPE 243 app developers, or anyone else interested in developing an app like this.

1. Grant the phone permission to establish a bluetooth connection and access its location. We needed three to get started:
BLUETOOTH
BLUETOOTH ADMIN
ACCESS COARSE LOCATION

These permissions were included in the Application's manifest file.

Google Maps Integration

Technical Challenges

<Bullet or Headings of a module>

Bug Tracking

<Problem Summary> <Problem Resolution>

Bill Of Materials

ANDROID MOBILE APPLICATION

PART NAME

PART MODEL

QUANTITY

COST PER UNIT (USD)

  • Android Mobile Phone
  • Samsung Galaxy S4
  • 1
  • N/A (Supplied by Nuoya Xie)


BRIDGE CONTROLLER

Hardware Design

The Bridge controller acted as an interface between the Android mobile phone and the car. Its main purposes were to start and stop the car wirelessly and to send destination (latitude and longitude) coordinates to the geographic controller, for use with its pathfinding algorithm.

Our approach, involved pairing an HC-05 bluetooth transceiver with the Android mobile phone and then transmitting coordinates to and from the bridge controller using UART. Checkpoints along the path-to-goal, were transmitted over CAN, to the bridge, from the geographic controller.

Upon startup, 3.3V was supplied to the HC-05.

When the user clicked the "Discover" button the app, the Android mobile phone, initiated a pair and connect sequence, with the HC-05 (using its MAC address). Upon a successful pairing, the HC-05's LED blinks slowly as opposed to a few times a second (when unpaired).

The HC-05 used UART transmit and receive queues on the SJOne board, to store data, before transmitting it to the mobile app over bluetooth.

Bridge Controller Schematic
RUN DBC Bridge Sch.jpeg

Software Design

Periodic Callback: Init

Upon startup, the bridge controller initiated both its UART and CAN peripherals. In order to communicate with the Android mobile phone over bluetooth, we had to use a baud rate of 9600bps. We set our transmit and receive queue sizes to 64 bytes, respectively. We also reset the CANbus, in order to ensure proper functionality.


Periodic Callback: 1Hz

In order to verify that the Bridge Controller's CAN transceiver was operational, we sent a heartbeat message every 1Hz, to the master controller. We used an integer value '0', for simplicity. If the bridge's CAN transceiver malfunctioned, the master controller illuminated the first (onboard) LED on itself (SJOne board). This allowed us to detect MIA modules quickly, without needing to connect to the Busmaster immediately.

We also checked the status of the CANbus every 1Hz and reset the bus if it was not operational. This was to ensure that a CAN glitch would not permanently compromise the bridge controller.


Periodic Callback: 10Hz

As stated before, the Bridge Controller acted as an interface between the Android Mobile phone and the car. Therefore we needed to transmit and receive coordinates and command from the phone, as well as to/from other modules on the car.

We checked the UART receive queue for START and STOP commands from the Android mobile phone. If one was received, then a CAN message was transmitted to the Master Controller, suggesting that it either apply or terminate power to the motor. For simplicity, we sent a character, '1' for START and '0' for STOP.

We also checked for essential navigation data from the Geographic Controller and Sensor Controller. We expected the car's starting coordinates (latitude and longitude), heading, deflection angle and distance to destination from the Geographic Controller. From the Sensor Controller, we expected feedback from the front, middle and rear distance sensors, as well as the infrared sensor mounted on the back of the car. This data was stored in a UART transmit queue and then transmitted to the Android mobile phone over bluetooth, every 2Hz. The Android application displayed feedback from the Geographic and Sensor controllers below its Google Map fragment.


RUN DBC Bridge Software Flowchart.jpg

Technical Challenges

UART Receive While Loop

The primary technical challenge that we encountered, while developing the Bridge Controller, occurred during a demo. In an effort to display readings from sensor and geo on the Android application in real time, "CAN Receive" function was used, which in turn used a while loop to receive all CAN messages and then extract geo and sensor data, parse them and send them over UART to android application. Initially, we compiled all the data received and sent them within the CAN receive function which caused the app to crash/display junk values. To overcome this we replaced the while loop with if, however, this slowed down the rate at which messages were received and we displayed old data on App. It took a while to figure out, but we created a new function called compile and send where we concatenated data and called it at 2Hz which fixed the issue.

interfacing between bridge and geographic modules

Another challenge we faced is the task of interfacing between geographic and bridge modules. Not long after starting the task, we realized that timing is very important. Since Dijkstra path-finding algorithm is only needed to run once, we need to make sure we obtain destination from Android phone first before running the algorithm. We also had to make sure geographic module receives the checkpoint from bridge module first before doing the bearing and distance calculations. We solved the first issue by setting a flag for Dijkstra algorithm. Every second the SJone board will check to see if the destination structure is populated. If it is, it sets a flag that enables the population of matrix needed by the algorithm and the algorithm itself is run shortly after. Latter issue by inputting a dummy distance of 1000m as the output of our distance calculation, before any checkpoint data arrives from bridge module. If a value of 1000 is showing on the LCD screen attached to the car, we know that geographic module has not yet gotten a checkpoint coordinate from bridge.

Bill Of Materials

BRIDGE CONTROLLER

PART NAME

PART MODEL

QUANTITY

COST PER UNIT (USD)

  • Bluetooth Serial Communication Module
  • 1
  • N/A


GEOGRAPHIC CONTROLLER

Hardware Design

The geographical controller is responsible for providing the required directions for the car to reach its destination. This is achieved using the Adafruit MTK3339 Ultimate GPS module and the CMPS14 9DOF compass module to obtain the heading, bearing, and distance to checkpoint. Geographical controller receives checkpoint from bridge module, with which the distance and deflection angle are calculated. In our design, the pathfinding and the continuous sending of different checkpoints as car reaches each of them is checked by the Bridge module. The geographic controller is only responsible for obtaining the car’s current coordinates, computing distance and angle to the next checkpoint that is provided by the Bridge module over CAN and send these results over the CAN bus.

The car's starting latitude and longitude coordinates, were calculated by the GPS and then transmitted over CAN to the bridge controller, which transmitted them to the Android phone, using bluetooth. Upon executing the RUN-D.B.C Android mobile application, the user was able to select a destination location, by placing a marker on the Google Map fragment. The app parsed the destination's latitude and longitude coordinates and then sent them to the bridge controller. The pathfinding algorithm (Dikstra's algorithm) is used to calculate a path to the destination based on the starting location and a series of pre-defined checkpoints comprised of longitude and latitude data.

Geographic Controller Schematic

RUN DBC geo sch.jpeg


GPS Module

S19 RUNDBC.jpg
S19 RUNDBC antenna.jpg


As stated before, we used an Adafruit MTK3339 Ultimate GPS module. The GPS, along with the compass, was responsible for calculating bearing angle and distance from destination checkpoints. An external antenna was integrated, in order to help parse the GPS data more efficiently. The GPS module used UART, to communicate with the SJOne board. The baud rate for the UART interface had to be initialized twice: 9600 bps at first and then again at 57600 bps. This was because the Ultimate GPS module could only receive data at 9600 bps upon startup, but its operational baud rate was specified as 57600 bps.

The GPS module came with a GPS lock, which allowed it to use satellite feedback to parse its location. This lock was indicated by an LED, which illuminated once every 15 seconds. If no lock was found then the LED illuminated once every 1-2 seconds. The parsing of data from the GPS was in terms of NMEA sentences, each of which had a specific functionality. Out of the several NMEA sentences, $GPRMC was used. It provided essential information, such as latitude and longitude coordinates. The $GPRMC sentence is separated by commas, which the user had to parse in order to get useful data out of the module. The strtok() function was used to parse data from the GPS module, with comma(,) as the delimiter.


The $GPRMC sentence looks like this: $GPRMC,225446,A,4916.45,N,12311.12,W,000.5,054.7,191194,020.3,E*68

The below table explains what each of the datum in the GPRMC sentence stands for:


RUN DBC geo table pic.png


The first 6 fields in the NMEA sentence are the most important ones. If field 4 said ‘N’, we checked the data in field 3 which had the latitude. Likewise, if field 6 said ‘W’, we check the data in field 5 which contained the longitude. It is important to note that the longitude and latitude data are in the form degree-minute-seconds instead of true decimal. If not properly converted, they could have offset the location readings by miles.

Compass Module

Compass rundbc.jpg

The compass module is responsible for redirecting/navigating the car towards the required destination as chosen on the mobile app. The heading angle is obtained from the compass module, which tells us where the car is pointing to the magnetic north. Since it is true north that we want, we need to add an offset, called magnetic declination, to the heading angle.

The compass module chosen is CMPS14 – Tilt compensated compass module which has a 3-axis gyro, 3-axis accelerometer and a 3-axis magnetometer. It is powered on by 3.6-5V but works on 3.3V too. It uses I2C to communicate with the SJOne board for which the mode pin can be left open or pulled up to the supply voltage. Due to the presence of the magnetometer, the compass must be placed away from all other components of the car to minimize magnetic interferences from other controllers. In our car, the compass was placed at an elevated position, high enough to be away from other controllers’ magnetic interferences. The compass need not be calibrated manually, as CMPS14 has automatic calibration.

Read Compass Heading

Compass heading is read by initiating the I2C read operation, and by passing the compass address (0xC0) and the register address (0x2). These values, along with the temporary array must be passed in a single I2C read operation. An example of the code snippet is as below:

if (read_byte_from_i2c_device(COMPASS_ADDRESS, first_reg_address, 2, temp)) {
   temp_result = temp[0] << 8 | temp[1];
   float temp_float = temp_result / 10.0;  // from 3599 to 359.9  
   temp_float += 13.244;   // correct for magnetic declination
   if (temp_float >= 360) {
     temp_float -= 360;
   }
   *result = temp_float;
   return true;
 }
 return false;
Check Compass Calibration

The calibration level is checked to see how well the compass is calibrated. The 8-bit value resides in register 0x1E according to the diagram below:

Compass calibration rundbc.jpg

When each of the 2-bit calibration value is 0, this means the specific field is not calibrated, a value of 3 means the field is fully calibrated. This is done by performing an I2C read operation, whilst reading the 0xC0 and the 0x1E registers, to determine if it’s calibrated or not. The code snippet looks as below:

bool check_calibration_level(uint8_t* result) {
 char calibration_state_address = 0x1E;  // register 30
 bool is_calibration_successful = false;
 if (read_byte_from_i2c_device(COMPASS_ADDRESS, calibration_state_address, 1, result)) {
   is_calibration_successful = true;
 }
 return is_calibration_successful;
 }

Essential GPS Data

Bearing, Distance, and deflection angle Calculation

Bearing, calculated as an angle from true north, is the direction of the checkpoint from where the car is. The code snippet to calculate bearing is below. Lon_difference is the longitude difference between checkpoint and current location. GPS is the current location, and DEST is checkpoint location. For all trig functions used below, the longitude and latitude values have to be converted to radian. After the operations, the final bearing angle is converted to degrees and a positive value between 0 and 360.

bearing = atan2((sin(lon_difference) * cos(DEST.latitude)), ((cos(GPS.latitude) * sin(DEST.latitude)) - (sin(GPS.latitude) * 
cos(DEST.latitude) * cos(lon_difference))));
   bearing = (bearing * 180) / PI;
   if (bearing <= 0) bearing += 360;
      return bearing;

Distance between the car and the checkpoint can be calculated using GPS along. The code snippet to calculate distance is shown below. It utilizes the haversine formula to calculate the great-circle distance between two points on a sphere given their longitudes and latitudes. Like the bearing calculation, all coordinates must be in radian. The value 6371 below is earth’s radius in km.

float a = pow(sin((DEST.latitude - GPS.latitude) / 2), 2) + cos(GPS.latitude) * cos(DEST.latitude) * 
pow(sin((DEST.longitude - GPS.longitude) / 2), 2); 
float c = 2 * atan2(sqrt(a), sqrt(1 - a)); 
float distance = 6371 * 1000 * c; 
return distance;

After obtaining heading and bearing values, deflection angle, the difference in angle between your car and the checkpoint, is calculated. This is the angle value that is given to the master for steering purposes. We made that if the deflection angle is negative, the car should steer to the left. If the angle is positive, then the car should steer to the right.

deflection = gps_bearing - compass_heading;
 if (deflection > 180)
   deflection -= 360;
 else if (deflection < -180)
   deflection += 360;

Software Design

The complete flowchart for the geo module is shown below. We broke all the tasks in two iterations of the 10Hz function because if we do them in one iteration, we get the task overrun error. Therefore, the gps update rate is 5Hz.

Geo diagram rundbc.jpg

Technical Challenges

Getting correct BAUD rate for GPS

  • When we first started interfacing with GPS module, we can never get the gps to output the BAUD rate we want (57600). Hercules was showing random symbols when we switch BAUD rate to 57600 even though we made sure the message we send to the GPS was correct. Browsing through Adafruit's help forum showed that the GPS, upon startup, only accepts messages in 9600 bps. If the user wants to switch BAUD rate to a higher value, he/she has to first send the command to switch BAUD rate in 9600, then rest of the command can be in the higher BAUD rate. As soon as we added the missing component, our GPS was giving us correct information shown in Hercules.

Compass reading was not accurate and would deviate from initial calibration

  • The initial compass we got (CMPS12) exhibited unstable heading reading. Even after we calibrated manually to make sure it points to magnetic north, after some testing we would check again and it would not point to magnetic north anymore. We tried to both factory preset and manually saving calibration profiles but nothing changed. We ended up buying another compass (CMPS14) that offered the ability to turn off auto-calibration. At the start of the SJone board we send a command to the compass to disable auto-calibration and auto-profile saving, we lengthened the wooden rod that takes the compass away from the EM-generating components of the car, and we replaced our GPS antenna for one without build-in magnet. All of these things together solved our issue and our compass was accurate within 2-3 degrees from magnetic north, which is sufficient for our application.

Parsing NMEA sentences

  • When we are receiving NMEA sentences from the gps module, sometimes we would receive garbled up messages. Since our GPS module continuously send out NMEA sentences and lacks a trigger pin that send NMEA sentence when prompted, we have no idea, when we are using uart driver to read the message, when the start of the message will first appear. To solve this issue, we implemented several checks to our GPS parsing. First, the processing of the messages only happens if the first character of the message is the character '$', which begins our GPRMC sentence. Next, we will only take in latitude and longitude values if the third and fifth entries read are 'N' and 'W', respectively. These checks ensure that the message is not fragmented and allow us to obtain correct longitude and latitude data.

Bill Of Materials

GEOGRAPHIC CONTROLLER

PART NAME

PART MODEL

QUANTITY

COST PER UNIT (USD)

  • GPS
  • 1
  • $69.13
  • GPS ANTENNA
  • 1
  • $8.79
  • Compass
  • 1
  • $33.99


MASTER CONTROLLER

Hardware Design

The master controller is primarily interfaced with the other controllers over CAN bus. The other main interface is control of the LCD display for debug data, which communicates over UART.

RUN DBC master sch.png

Software Design

Master stateMachine.PNG
  • LCD display

The LCD is controlled over UART

  • CAN read and send
  • Navigation: The primary function of the master module is to process the geo and sensor data, and send steering and motor commands to the motor module.
    • obstacle avoidance
    • steer to checkpoint


The state machine above handles the data processing to decide what steering and motor commands to send to the motor module.

  1. INIT: The state machine always starts here. It sets the motor speed and direction to zero and the steering to straight before transitioning to the WAIT state.
  2. WAIT: The car will stay in this state with the motor set to zero speed and steering set to straight until there is a go command is received, and the distance to the next checkpoint is > 10 meters, at which point it transitions to the NAVIGATE state.
  3. NAVIGATE: While in this state, the master will set the motor command to the predetermined NAVIGATE_SPEED (2.0m/s standard) and the steering angle based on the deflection between the bearing to the next checkpoint and the heading of the car.
  4. OBSTACLE LEFT/RIGHT: These states are triggered when the left or right ultrasonic sensor detect an object closer than the STEER_THRESHOLD, and will command the motor speed to OBSTACLE_SPEED and steer in the opposite direction of the obstacle.
  5. OBSTACLE MID FAR: This will be triggered when there is an obstacle straight ahead closer than the MIDDLE_THRESHOLD_FAR (and has a higher priority than the left and right obstacle states). The module will command the speed to OBSTACLE_SPEED and attempt to steer around the obstacle to the right.
  6. OBSTACLE MID CLOSE: This will be triggered when there is an obstacle straight ahead closer than the MIDDLE_THRESHOLD_CLOSE (and has the highest priority). The car will be commanded to drive backwards if there is nothing behind the car, or stop in place if there is something behind the car, until the front obstacle is cleared or far enough away to attempt to navigate around it.
  7. REVERSE_PAUSE: This is a short pause after the OBSTACLE MID CLOSE state. This allows the car to coast to a stop before commanding forward again, to avoid integral wind-up of the PI controller on the Motor module.

Technical Challenges

  • Quickly switching from reverse to forward "winds up" integral term of PI controller on motor module
    • Solved by adding short (1 second) delay after reversing

Bug Tracking

  • One of the MIA LEDs would blink, even when the appropriate node was on the CAN bus and messages were being received.
    • Probable related to not properly cleaning the build after making some changes. The problem resolved itself

Bill Of Materials

MASTER CONTROLLER

PART NAME

PART MODEL

QUANTITY

COST PER UNIT (USD)

  • SJOne board
  • NA
  • 1
  • $70


MOTOR CONTROLLER

Hardware Design

The motor board was responsible for both steering and spinning the wheels in order to move the car towards the target destination.
The front 2 wheels of the car handled the steering portion and it accomplished this with the utilization of the servo.
The back 2 wheels of the car handled spinning the wheels and it accomplished this through the utilization of the Electronic Speed Control (ESC) that was interfaced to the DC motor directly.

The servo was included with the RC we purchased and it was interfaced with 3 pins:
1 pin for the power supply, which was powered by the battery that came with the RC car (as opposed to the same supply that other components shared on our PCB)
1 pin for the ground signal
1 pin for the servo dedicated PWM control signal

The ESC was included with the RC we purchased and it was interfaced with 3 pins:
1 pin for the power supply (powered similar to the servo)
1 pin for the ground signal
1 pin for the ESC dedicated PWM control signal

Managing the steering was relatively simple. The servo mainly requires a PWM signal in order to operate.
As seen through the timing diagrams below (and through experimentation), we found the frequencies and duty cycles that corresponded to actual steer left, steer right, and steer straight.
With our SJ1 board, we were able to match our frequencies and duty cycles and steer the car using the APIs that we designed.
Our code does allow for the steering to be set to any turn angle that is mechanically allowed by the car.
In order to reach the maximum turn angle setting, the programmer needs to set the PWM to either 10% (left) or 20% (right) duty cycle.
If the programmer wants a smaller turn angle, they need to program the PWM to a duty cycle that is closer to 15% (15% duty cycle means steer straight).

Managing wheel spin was a more complicated process. The ESC also requires a PWM signal in order to operate, but is not as simple as the servo's operation.
In order to reach the maximum speed in the forward direction, the programmer needs to set the PWM duty cycle to 20%.
In order to stop spinning the wheels, the programmer needs to set the PWM duty cycle to 15%.
In order to safely reverse the car, the RC car manufacturer implemented a special feature to make sure that the DC motor doesn't burn up when switching from high speed forward to going in the reverse direction.
When controlling the car with the handheld RC remote (manual control), this feature is present and the user needs to first stop and toggle some reverse commands before the car can actually move in reverse.
This means that a state machine was also needed in our code in order to enable reverse functionality.
Our software implementation of this reverse state machine is:
Stop for 100ms
Reverse for 100ms
Stop for 100ms
Reverse for 100ms
User can then reverse at any given PWM duty cycle from <15% (low speed) to 10% (full speed)


In order to maintain constant speed while moving up/down an inclined road, a Proportional-Integral-Derivative (PID) loop is commonly used.
We didn't find the need to include the derivative component, so our speed control loop just contained the proportional and integral components.
Actual moving car speed is another component of this loop, we were able to read and calculate actual car speed through the use of an encoder.
Portions of the PID loop use constant values for the gains of each component.
Our gains were determined through a trial and error testing process.


Speed Control Timing Diagrams

Run DBC Speed timing diagrams.PNG


Steering Control Timing Diagrams

Run DBC Steering timing diagrams.PNG


Motor Controller Schematic
RUN DBC motor sch.png

Software Design

<List the code modules that are being called periodically.>


Technical Challenges

<Bullet or Headings of a module>

  • We had to change the PWM driver to hard code the sys_clock frequency. We found solution.
  • Original encoder sourced is was designed to be a knob, not a motor encoder. The additional rotational resistance caused vibrations and resulted in it becoming disconnected from the motor shaft several times. The solution was to us a slightly more expensive encoder, designed for higher speed continuous operation on a motor.


Bill Of Materials

MOTOR CONTROLLER

PART NAME

PART MODEL

QUANTITY

COST PER UNIT (USD)



SENSOR CONTROLLER

Hardware Design

Image002.jpg

We gave a lot of thought regarding how and where sensors should be mounted to the car. In order to facilitate adjusting the directions of individual sensors, we incorporated circular grooves in the sensor bases. The hinge of the sensor mount also allowed sensors to be vertically adjusted Together with the sensor mount, this approach gave the sensor's two degrees of freedom.

Sensor Controller Schematic
RUN DBC sensor sch.png


CAD Design

The picture on the left shows that the hinge of the sensor guard can be adjusted to minimize the amount of interference between sensors.
The picture on the right shows the hinge of the sensor mount, allowing vertically adjustment.

SW001.gif
SW002.gif


Placement for the Ultrasonic Sensors

We realized that when the sensors were active, the left and right sensor ultrasonic wave output, sometimes interfered with the middle sensor, resulting in incorrect feedback. This occurred despite polling the sensors in separate periodic tasks. We discovered that, mounting the middle sensor on a higher surface than the left and right sensors decreased the interference substantially. Furthermore, by attaching two guard pieces on the left/right sensors (acting as shields), we further decreased the interference between sensors. We rigorously tested the integrity of sensor feedback with the guards in different positions, to ensure that they didn't introduce interference of their own (in certain positions).

Software Design

Flowchart

The flow diagram for sensor is shown below. We split the sensor readings to two different 10Hz tasks to minimize amount of interference between left/right and middle sensors. In one of the iterations, we read the left/right ultrasonic sensors in parallel, and immediately after reading them we trigger the middle ultrasonic sensor. Since it takes time for sound waves to bounce back from solid surface, by the time the next task begins the middle ultrasonic sensor can then read the sensor value. In the other iteration, the middle and rear sensors are read, and left/right ultrasonic sensors are triggered to output sound wave. At the end, when all information are received by the SJone board, it is send out on the CAN bus in frequency of 5Hz. It is optional to use the trigger pin (RX) to trigger the sensors to send out ultrasonic waves, but we use it because instead of letting the sensors continuously outputting ultrasonic waves and allowing them to interfere with each other, it is better to let them output waves in bursts for a much cleaner signal.

Software003.png
Timing Diagram
Software002.jpg

Technical Challenges

Sensor Interference

We saw a lot of interference between the front 3 sensors. We were able to overcome the issue with both hardware and software tweaks:

  • Higher placement of middle ultrasonic sensor and interference guard for the left and right sensors
  • Instead of leaving the RX pin of the sensors unconnected, which causes the sensors to output ultrasonic waves continuously, we toggled the RX pin, to turn off sensor ranging and only allow wave output when we needed it. The periodic callback function was also written in a way that staggered sensor triggering and reading, to allow sufficient time to process the ADC feedback.
Power Deficiency

At first, when the sensors were tested individually (as well as together on early iterations of the car), they performed to specifications. However, when other subsystems were integrated into the car, the sensor feedback fluctuated wildly. After many hours of troubleshooting, we realized that our 1A power supply was not enough to supply sufficient power to all systems on the car. We addressed the problem by using a power supply with a 3.5A output.

Unstable HR-04 Readings

At first, we used two HC-SR04 modules, as our left and right sensors. However when we tested them during obstacle avoidance we realized that their range was too narrow to reliably detect obstacles. As a result we switched to more expensive, but reliable Maxbotix EZ line of sensors.

ADC Supply Voltage

The middle sensor's also fluctuated wildly at times. After hours of testing we realized that our 5V power supply was distorting its feedback signal, due to the SJOne's ADC peripheral being powered by 3.3V. Applying a 3V power signal to the middle sensor corrected the issue.

Slow car response to obstacle due to large queue size (running average)

During our first try at obstacle avoidance we found that the car reacts very slowly to obstacles, even though the sensor update rate is 10Hz. Later we found out that the reason is because of our queue implementation. We used to have a very large queue to calculate running average. This filters out spikes but also means when an obstacle is detected it takes very long time for the running average to be updated.

Decreasing the queue size and using the median value instead of the average value solved the issue.

Bill Of Materials

SENSOR CONTROLLER

PART NAME

PART MODEL

QUANTITY

COST PER UNIT (USD)

  • Infrared Sensor
  • 1
  • $13.95
  • Front-left-right Distance Sensor
  • 2
  • $29.95
  • Front-middle Distance Sensor
  • 1
  • $29.95


CONCLUSION

<Organized summary of the project>

<What did you learn?>

Project Video

Project Source Code

Advice for Future Students

<Bullet points and discussion>


Grading Criteria

  • How well is Software & Hardware Design described?
  • How well can this report be used to reproduce this project?
  • Code Quality
  • Overall Report Quality:
    • Software Block Diagrams
    • Hardware Block Diagrams
      Schematic Quality
    • Quality of technical challenges and solutions adopted.