Difference between revisions of "S24: Team Falcons"

From Embedded Systems Learning Academy
Jump to: navigation, search
(Schedule)
(Software Design)
 
(62 intermediate revisions by the same user not shown)
Line 6: Line 6:
  
 
== Abstract ==
 
== Abstract ==
<2-3 sentence abstract>
+
The Falcon RC car project is the combined efforts of our team to create an autonomously RC Car that avoids all obstacles and follow GPS to reach the destination. Here, we have put in all our experience in software design, hardware design, unit testing, power systems, and mobile application development. Project development started in March of 2024 and ended in May 2024.
  
 
=== Introduction ===
 
=== Introduction ===
  
The project was divided into N modules:
+
The project was divided into 4 modules:
  
* Sensor ...
+
* Sensor and Bridge Controller
* Motor..
+
* Driver Controller
* ...
+
* Geo Controller
* Android
+
* Motor Controller
 +
 
 +
Driver controller is the master controller that receive inputs from sensor controller and geo controller, and gives output commands to motor controller. The destination coordinate is send from Android application to sensor node via Bluetooth. The app also send a hard start and stop to the car. The car starts only on receiving start signal from the app and stops completely on receiving stop signal from app.
  
 
=== Team Members & Responsibilities ===
 
=== Team Members & Responsibilities ===
 
<Team Picture>
 
<Team Picture>
  
Gitlab Project Link - [https://gitlab.com/...]
+
Gitlab Project Link - https://gitlab.com/jincyjose491/sjtwo-c[https://gitlab.com/jincyjose491/sjtwo-c]
 
<BR/>
 
<BR/>
  
<Provide ECU names and members responsible>
 
<One member may participate in more than one ECU>
 
  
 
* Sensor
 
* Sensor
Line 52: Line 52:
 
<HR>
 
<HR>
 
<BR/>
 
<BR/>
 +
 
== Schedule ==
 
== Schedule ==
  
Line 96: Line 97:
 
* Discuss Android app design and development challenges
 
* Discuss Android app design and development challenges
  
| Not completed
+
| Completed
 
|-
 
|-
 
! scope="row"| 4
 
! scope="row"| 4
Line 109: Line 110:
 
* Create dbc file for CAN communication
 
* Create dbc file for CAN communication
  
| Not completed
+
| Completed
 
|-
 
|-
 
! scope="row"| 5
 
! scope="row"| 5
Line 116: Line 117:
 
|
 
|
 
* Bringup of ultrasonic sensors with SJ2 board-
 
* Bringup of ultrasonic sensors with SJ2 board-
* Connect the sensor with the board using header connectors.
+
** Connect the sensor with the board using header connectors.
* Check sensor functionality, obstacle detection.
+
** Check sensor functionality, obstacle detection.
* Create initial draft for PCB design.
+
** Create initial draft for PCB design.
  
 
* Bringup of bluetooth module with SJ2 board-
 
* Bringup of bluetooth module with SJ2 board-
* Connect the bluetooth module with the board using header connectors.
+
** Connect the bluetooth module with the board using header connectors.
* Check functionality, tx, rx, range.
+
** Check functionality, tx, rx, range.
* Create initial draft for PCB design.
+
** Create initial draft for PCB design.
  
 
* Bringup of motor controller with SJ2 board-
 
* Bringup of motor controller with SJ2 board-
* Disassemble the RC car, understand internal electrical connections, derive connections to control steering and drive the motor.
+
** Disassemble the RC car, understand internal electrical connections, derive connections to control steering and drive the motor.
* Control the steering and drive motor via SJ2 board.
+
** Control the steering and drive motor via SJ2 board.
* Connect the encoder(RPM module) to the wheel and measure distance traveled.
+
** Connect the encoder(RPM module) to the wheel and measure distance traveled.
* Create initial draft for PCB design.
+
** Create initial draft for PCB design.
  
 
* Bringup of GPS and Magnetometer module with SJ2 board-
 
* Bringup of GPS and Magnetometer module with SJ2 board-
* Interface GPS module with SJ2 board and send data via CAN  
+
** Interface GPS module with SJ2 board and send data via CAN  
* Interface magnetometer with SJ2 board and send data via CAN  
+
** Interface magnetometer with SJ2 board and send data via CAN  
* Create initial draft for PCB design.
+
** Create initial draft for PCB design.
  
 
* Bring up of  LCD with SJ2 board  
 
* Bring up of  LCD with SJ2 board  
* Interface LCD with SJ2 board  
+
** Interface LCD with SJ2 board  
* Create initial draft for PCB design.
+
** Create initial draft for PCB design.
  
 
| Completed
 
| Completed
Line 147: Line 148:
 
|
 
|
 
* Bringup of entire system
 
* Bringup of entire system
* Connect all the different modules together.
+
** Connect all the different modules together.
* Validate CAN tx and rx among the modules.
+
** Validate CAN tx and rx among the modules.
* Develop integration tests.
+
** Develop integration tests.
* Create initial draft for PCB design.
 
* Calculate power requirement and run battery load test.
 
* PCB development
 
  
| Completed
+
| completed
 
|-
 
|-
 
! scope="row"| 7
 
! scope="row"| 7
Line 161: Line 159:
 
|
 
|
 
* Design and code  initial draft of obstacle avoidance algorithm
 
* Design and code  initial draft of obstacle avoidance algorithm
* Design and code initial draft of waypoint algorithm
 
 
* Design and code initial draft of Android app
 
* Design and code initial draft of Android app
 
* Finalize on power management
 
* Finalize on power management
Line 176: Line 173:
 
* Validate initial draft of obstacle waypoint algorithm.
 
* Validate initial draft of obstacle waypoint algorithm.
  
| Completed
+
| Not completed
 
|-
 
|-
 
! scope="row"| 9
 
! scope="row"| 9
Line 187: Line 184:
 
* Fine tune sensors for accuracy  
 
* Fine tune sensors for accuracy  
 
* Outdoor testing
 
* Outdoor testing
 
+
| Not completed
 
|-
 
|-
 
! scope="row"| 10
 
! scope="row"| 10
Line 193: Line 190:
 
| 04/30/2024
 
| 04/30/2024
 
|
 
|
* Literature survey- previous year project reports, hardware used, algorithms, challenges, advice to future students.
+
* Prototype 3:
* Ordered CAN transceivers.
+
* Release obstacle avoidance logic version 2
 +
* Release waypoint algorithm version 2
 +
* Outdoor testing version 2
  
 +
| Not completed
 
|-
 
|-
 
! scope="row"| 11
 
! scope="row"| 11
Line 201: Line 201:
 
| 05/07/2024
 
| 05/07/2024
 
|
 
|
* Literature survey- previous year project reports, hardware used, algorithms, challenges, advice to future students.
+
* Final project demo
* Ordered CAN transceivers.
 
  
 +
| Not completed
 
|-
 
|-
! scope="row"| 12
 
| 05/07/2024
 
| 05/14/2024
 
|
 
* Literature survey- previous year project reports, hardware used, algorithms, challenges, advice to future students.
 
* Ordered CAN transceivers.
 
  
 
| Completed
 
 
|}
 
|}
  
Line 232: Line 224:
 
| Traxxas
 
| Traxxas
 
| 1
 
| 1
| $250.00
+
| $265.00
 
|-
 
|-
 
! scope="row"| 2
 
! scope="row"| 2
| CAN Transceivers MCP2551-I/P
+
| SJ2 boards
| Microchip [http://www.microchip.com/wwwproducts/en/en010405]
+
| CMPE SCE
| 8
+
| 4
| Free Samples
+
| $50.00 each
 +
|-
 +
! scope="row"| 3
 +
| CAN Transceivers
 +
| Adafruit [https://www.adafruit.com/product/5708]
 +
| 4
 +
| $3.95 each
 +
|-
 +
! scope="row"| 4
 +
| Ultrasonic sensor
 +
| Adafruit [https://www.adafruit.com/product/172]
 +
| 4
 +
| $114.00
 +
|-
 +
! scope="row"| 5
 +
| GPS PA1616S BREAKOUT
 +
| Digikey [https://www.digikey.com/en/products/detail/adafruit-industries-llc/746/5353613]
 +
| 1
 +
| $29.95
 +
|-
 +
! scope="row"| 6
 +
| LSM303AGR ACC COMPASS
 +
| Digikey [https://www.digikey.com/en/products/detail/adafruit-industries-llc/4413/10709727]
 +
| 1
 +
| $12.50
 +
|-
 +
! scope="row"| 6
 +
| LSM303AGR ACC COMPASS
 +
| Digikey [https://www.digikey.com/en/products/detail/adafruit-industries-llc/4413/10709727]
 +
| 1
 +
| $12.50
 +
|-
 +
! scope="row"| 7
 +
| LCD Display
 +
| Amazon [https://www.amazon.com/dp/B01GPUMP9C?ref=ppx_yo2ov_dt_b_product_details&th=1]
 +
| 1
 +
| $12.99
 +
|-
 +
! scope="row"| 8
 +
| RPM sensor
 +
| Traxxas [https://traxxas.com/products/parts/telemetry/6520]
 +
| 1
 +
| $12.00
 
|-
 
|-
 
|}
 
|}
Line 294: Line 328:
 
== Geographical Controller ==
 
== Geographical Controller ==
  
<Picture and link to Gitlab>
+
Geo controller: https://gitlab.com/jincyjose491/sjtwo-c/-/tree/master/projects/geo_controller?ref_type=heads
 +
 
 +
Navigation in modern systems seamlessly integrates GPS with compass technology to enhance driving experience and safety. GPS provides accurate location data by communicating with satellites, while the compass offers directional orientation of the vehicle. This combination is essential also in the RC car project as it enables the vehicle to autonomously maneuver to a given detsination coordinate. The GPS modules keeps track of the current position of the car, provides the direction that the car should move towards and the compass module keeps track of the direction in which the car is actually heading. Integrating the two modules, an algorithm has been developed as elaborated below to achieve the complete autonomous functionality.
  
 
=== Hardware Design ===
 
=== Hardware Design ===
 +
 +
The Geo controller is interfaced to both the GPS module and the compass modules. Both these modules are powered using stable 3.3V inputs which are derived from the SJ Two boards. The GPS communicates with the board via UART and is connected to the controller at the P4.28 and P4.29, Rx and TX pins respectively. The GPS requires an antenna which is interfaced to the module via a UFL to SMA connector. Though the GPS module houses an led to indicate FIX on GPS lock, the led3 of SJTwo board was used to also show lock acquired after GPS string was received. The compass module communicates with the board via I2C and is connected at P0.10 SDA and P0.11 SCL pins respectively. As part of the hardware design, the compass module was mounted on a separate long pole, away from other interferences. The led1 of SJTwo board was used to indicate a successful comapss read.
 +
 +
 +
[[File:Geo compass.jpg | 300px | thumb | center | Compass module ]]
 +
 +
 +
[[File:Geo gps.jpg | 300px | thumb | center | GPS module]]
 +
 +
 +
 +
<Layout pic>
  
 
=== Software Design ===
 
=== Software Design ===
<List the code modules that are being called periodically.>
+
 
 +
The GPS module provides data in the form of NMEA strings. NMEA (National Marine Electronics Association) is a standard protocol used by GPS receivers to transmit data. These strings contain various pieces of information, such as latitude, longitude, altitude, and time. The data bytes sent from the GPS module through UART are first loaded into a line buffer. The algorithm then parses this buffer to capture the specific $GPGGA strings that includes the correct position, time, and fix status.
 +
 
 +
[[File:Geo gpgga table.png | 450px | thumb | center | $GPGGA string parameters]]
 +
 
 +
 
 +
Following is the GPS string parsing logic where the lattitude and longitude are retrieved:
 +
 
 +
<syntaxhighlight lang="cpp">
 +
 
 +
static gps_coordinates_t gps_string_to_coordinates(char gps_line[line_buffer_size]) {
 +
  gps_coordinates_t coordinates = {0, 0};
 +
  char gps_line_copy[line_buffer_size];
 +
  strcpy(gps_line_copy, gps_line);
 +
  char *token = strtok(gps_line_copy, ",");
 +
  int token_count = 0;
 +
  char *tokens[6];
 +
  while (token != NULL && token_count < 7) {
 +
    if (token_count == 2 || token_count == 3 || token_count == 4 || token_count == 5 || token_count == 6) {
 +
      tokens[token_count - 2] = token;
 +
    }
 +
    token = strtok(NULL, ",");
 +
    token_count++;
 +
  }
 +
 
 +
  // Check GPS Quality indicator value != 0 to see if FIX acquired
 +
  if (strtof(tokens[4], NULL)) {
 +
    GPS_fix_acquired = true;
 +
 
 +
    coordinates.latitude = strtof(tokens[0], NULL);
 +
    char *latitude_dir = tokens[1];
 +
    coordinates.longitude = strtof(tokens[2], NULL);
 +
    char *longitude_dir = tokens[3];
 +
    if (*latitude_dir == 'S')
 +
      coordinates.latitude *= -1;
 +
    if (*longitude_dir == 'W') {
 +
      coordinates.longitude *= -1;
 +
    }
 +
  }
 +
  return coordinates;
 +
}
 +
 
 +
</syntaxhighlight>
 +
 
 +
The compass module required calibration to provide accurate results. This was accomplished using MotionCal software, interfaced with an Arduino. After determining the hard and soft iron offsets, these values were applied in the code to perform software-based compass calibration. The compass heading relative to true north was then calculated based on the mounting direction. Proper register configuration was necessary to initialize the module and read the compass readings accurately.
 +
 
 +
[[File:Geo MotionCal calib.png | 450px | thumb | center | Compass calibration]]
 +
 
 +
Following is the compass register settings for proper initialization:
 +
 
 +
<syntaxhighlight lang="cpp">
 +
 
 +
void compass__init() {
 +
  i2c__initialize(current_i2c, i2c_baudrate_hz, clock__get_peripheral_clock_hz(), &binary_semaphore_struct,
 +
                  &mutex_struct);
 +
  uint8_t ctrl_reg1_value = 0x8C;
 +
  uint8_t ctrl_reg2_value = 0x02;
 +
  uint8_t ctrl_reg3_value = 0x10;
 +
  i2c__write_single(current_i2c, magnetometer_write, MAGNETOMETER_CTRL_REG1, ctrl_reg1_value);
 +
  i2c__write_single(current_i2c, magnetometer_write, MAGNETOMETER_CTRL_REG2, ctrl_reg2_value);
 +
  i2c__write_single(current_i2c, magnetometer_write, MAGNETOMETER_CTRL_REG3, ctrl_reg3_value);
 +
}
 +
 
 +
</syntaxhighlight>
 +
 
 +
 
 +
'''Checkpoint Algorithm'''
 +
 
 +
The checkpoint algorithm finds the nearest checkpoint coordinate based on the current location among a series of checkpoints, considering also the distance to destination coordinates. Initially, it calculates the distance between the current location and the destination. Then, it iterates through each checkpoint, finding the distance from the current location to the checkpoint and from the checkpoint to the destination. If both distances are less than the minimum distance to the destination found so far, it updates the minimum distance and sets the next checkpoint accordingly. Finally, it returns the coordinates of the closest checkpoint considering the destination. This ensures proper navigation by selecting the most relevant checkpoint.
 +
 
 +
<syntaxhighlight lang="cpp">
 +
 
 +
gps_coordinates_t find_closest_checkpoint_coordinate(gps_coordinates_t current_coordinate,
 +
                                                    gps_coordinates_t destination_coordinate) {
 +
  float min_distance_to_destination =
 +
      coordinates__get_distance_to_destination(current_coordinate.latitude, current_coordinate.longitude,
 +
                                              destination_coordinate.latitude, destination_coordinate.longitude);
 +
  gps_coordinates_t next_checkpoint = destination_coordinate;
 +
 
 +
  for (uint8_t index = 0; index < max_checkpoints; index++) {
 +
    float distance_to_waypoint =
 +
        coordinates__get_distance_to_destination(current_coordinate.latitude, current_coordinate.longitude,
 +
                                                checkpoints[index].latitude, checkpoints[index].longitude);
 +
    float distance_from_waypoint_to_destination =
 +
        coordinates__get_distance_to_destination(checkpoints[index].latitude, checkpoints[index].longitude,
 +
                                                destination_coordinate.latitude, destination_coordinate.longitude);
 +
 
 +
    if (distance_to_waypoint < min_distance_to_destination &&
 +
        distance_from_waypoint_to_destination < min_distance_to_destination) {
 +
      min_distance_to_destination = distance_to_waypoint;
 +
      next_checkpoint = checkpoints[index];
 +
    }
 +
  }
 +
  return next_checkpoint;
 +
}
 +
 
 +
</syntaxhighlight>
  
 
=== Technical Challenges ===
 
=== Technical Challenges ===
  
< List of problems and their detailed resolutions>
+
As the geo logic came as the final step in the project, it could only be tested thoroughly after all other modules performed reliably. Several issues were identified and resolved on the geo controller side:
 +
 
 +
* '''Problem''': The compass was giving unreliable values and not pointing to true north.
 +
** '''Solution''': The compass needed to be calibrated for the environment in which it was used, especially with the motor running.
 +
 
 +
* '''Problem''': The compass was giving a fixed range of values 170-250 dgrees, instead of the full 0-359 range, despite repeated calibrations.
 +
** '''Solution''': The register configurations had to be updated. Specifically, the block data update needed to be set, and offset cancellation had to be enabled.
 +
 
 +
* '''Problem''': The GPS was giving no parsed outputs.
 +
** '''Solution''': The issue was traced back to soldering errors. The TX and RX wires were not swapped correctly; the TX of the board needed to connect to the RX of the GPS module, and vice versa.
 +
 
 +
* '''Problem''': GPS was not acquiring stable lock inspite of testing it in open space and having the antenna connected.
 +
** '''Solution''': A button cell was added to the GPS module in the slot (rear side) provided in the module which enabled it to acquire locks faster.
 +
 
 +
* '''Problem''': GPS parsing was incorrect and not returning proper data.
 +
** '''Solution''': The line buffer size was increased, and it was ensured that a lock was obtained before reading the data.
  
 
<HR>
 
<HR>
Line 310: Line 469:
 
<HR>
 
<HR>
 
<BR/>
 
<BR/>
 +
 
== Communication Bridge Controller & LCD ==
 
== Communication Bridge Controller & LCD ==
 
<Picture and link to Gitlab>
 
<Picture and link to Gitlab>
Line 324: Line 484:
 
<HR>
 
<HR>
 
<BR/>
 
<BR/>
== Master Module ==
+
== Driver Node ==
  
<Picture and link to Gitlab>
+
Gitlab Link: https://gitlab.com/jincyjose491/sjtwo-c/-/tree/master/projects/driver?ref_type=heads
 +
 
 +
[[File:Falcon_LCD.jpeg|350px|center|thumb|LCD Display]]
  
 
=== Hardware Design ===
 
=== Hardware Design ===
 +
 +
Driver node gives the interconnection between input and output. It receives input from geo node and sensor node and give commands to the motor node. The only hardware driver has is the LCD display and CAN transceiver.  The LCD display used is a SunFounder IIC I2C TWI Serial 2004 20x4 LCD Module and is interfaced through an I2C bus through the I2C2 port. The module used and pin connections for LCD is shown below.
 +
 +
[[File:LCD Module.jpg|350px|center|thumb|LCD Display]]
 +
 +
{| style="margin-left: auto; margin-right: auto; border: none;"
 +
|-
 +
|
 +
{| class="wikitable"
 +
|+ Table 6. LCD Display Pinout
 +
|-
 +
! SJTwo Board
 +
! CAN Board
 +
|-
 +
| P0.11
 +
| SCL2
 +
|-
 +
| P0.10
 +
| SDA2
 +
|-
 +
| Vin
 +
| 3.3
 +
|-
 +
| GND
 +
| GND
 +
|}
 +
|}
  
 
=== Software Design ===
 
=== Software Design ===
<List the code modules that are being called periodically.>
+
 
 +
Driver has more software and less hardware. For navigation, there are two algorithms - obstacle avoidance and GPS navigation. Obstacle avoidance has precedence over GPS navigation. In case of any obstacle, car avoids obstacle. In other cases, it follows the path from geo node input. When the destination is reached, car slows down and stops.
 +
 
 +
=== Obstacle Avoidance ===
 +
 
 +
The obstacle avoidance code is written in the form of a truth table that has 4 bit input and one bit output. Inputs are four sensor values and output the motor commands. Bases on changes in sensor values, the motor command also changes. The logic that worked for us is given below
 +
 
 +
{| style="margin-left: auto; margin-right: auto; border: none;"
 +
|-
 +
|
 +
{| class="wikitable"
 +
|+ Table 6. Obstacle Avoidance Logic
 +
|-
 +
! left sensor
 +
! right sensor
 +
! middle sensor
 +
! rear sensor
 +
! motor command
 +
|-
 +
| 0
 +
| 0
 +
| 0
 +
| X
 +
| follow GPS navigation
 +
|-
 +
| 0
 +
| 1
 +
| 0
 +
| X
 +
| forward left
 +
|-
 +
| 1
 +
| 0
 +
| 0
 +
| X
 +
| forward right
 +
|-
 +
| 0
 +
| 1
 +
| 1
 +
| 0
 +
| reverse right
 +
|-
 +
| 1
 +
| 0
 +
| 1
 +
| 0
 +
| reverse left
 +
|-
 +
| X
 +
| X
 +
| 1
 +
| 1
 +
| stop
 +
|-
 +
| 1
 +
| 1
 +
| 0
 +
| 0
 +
| reverse left
 +
|-
 +
|}
 +
|}
 +
 
 +
=== GPS Navigation ===
 +
For GPS navigation the angle difference between heading and bearing is calculated and motor turn commands are generated based on this. Heading gives the current position in angle with respect to north. Bearing gives the angle to destination with respect to north. The logic that worked for our hardware is given below:
 +
 
 +
{| style="margin-left: auto; margin-right: auto; border: none;"
 +
|-
 +
|
 +
{| class="wikitable"
 +
|+ Table 6. GPS Logic
 +
|-
 +
! Angle difference = bearing - heading
 +
! Turn Angle
 +
|-
 +
| 0 to 180
 +
| left
 +
|-
 +
| 180 to 360
 +
| right [angle = (360 - angle)]
 +
|-
 +
| -180 to 0
 +
| right
 +
|-
 +
| -360 to -180
 +
| left [angle = fabs(360 + angle)]
 +
 
 +
|}
 +
|}
  
 
=== Technical Challenges ===
 
=== Technical Challenges ===
  
< List of problems and their detailed resolutions>
+
Since driver comes as the interconnect between all other nodes, the driver logic could be verified by outside testing only when we had stable input from geo and sensor node and motor nodes working as expected for given PWM. Unit testing can help in building of logic. But for actual test, we have to make sure all inputs are reliable. This can be verified with debug messages on bluetooth, CAN messages on busmaster, LCD display or LED indicators. The verification or debugging should be done in same frequency as which driver is processing.
 +
 
 +
* '''Problem''': LCD was not displaying anything.
 +
** '''Solution''': Initially tried with 3.3V supply, then 5V supply and finally added level shifter to I2C pins. But the issue was slave address given in the datasheet was wrong. I got the correct slave address from web serial. After this was corrected, LCD worked well with 3.3V.
 +
 
 +
* '''Problem''': LCD flickered a lot when everything was connected together.
 +
** '''Solution''': We initially connected all 5V supplies to a single 5V source. This included servo motor also. And it was causing the flicker. So, we powered up servo and rpm from ESC, all other sensors were powered separately from power bank and the issue was solved. This problem could have been avoided if more reports were read on how to power everything up.
 +
 
 +
* '''Problem''': Driver gave a reverse signal for one clock cycle when there was no obstacle.
 +
** '''Solution''': Sensors gave random value for just one clock cycle and this caused driver to generate reverse command. After sensor inputs were corrected and made stable, the problem was solved.
 +
 
 +
* '''Problem''': Driver not able to correct turning commands to motor even after sensing obstacle on side. This happened in the clock cycle when there was obstacle on all three side and it took reverse.
 +
** '''Solution''': We gave steps in angle changes in size of 5. Instead of direct 45 degree turn, car always turned in steps. So even though it sensed obstacle step sized turn angles took long clock cycles. So I finally reverted back to simple code logic of 45 degree turn and obstacle avoidance started working perfectly.
 +
 
 +
* '''Problem''': We thought driver was giving wrong commands to sensor values that was there on app.
 +
** '''Solution''': Sensor values were updated at 1 Hz. Driver was working at 10Hz which is 10 times faster than what we see on app. So incorrect sensor value for just one cycle was not displayed. Finally debugged it in a hard way from all debugging sources listed above.
  
 
<HR>
 
<HR>
 
<BR/>
 
<BR/>
 +
 
== Mobile Application ==
 
== Mobile Application ==
 
<Picture and link to Gitlab>
 
<Picture and link to Gitlab>
Line 366: Line 660:
  
 
=== Advise for Future Students ===
 
=== Advise for Future Students ===
<Bullet points and discussion>
+
 
 +
* Make sure you have a clear idea on how to power up every modules in the project. This require careful distribution of power across the boards, sensors, motors. Connect everything together in the initial stage to see if entire module can work well when connected together. Doing this at an early stage helps to understand how to correctly power up everything. Again, you'll get an idea on which all modules should/should not be connected together, which module require additional power source, etc. from previous reports. Most of your problems could be solved from previous year reports. Don't limit yourself to 2-3 reports. Read more.. It'll be useful.
 +
 
 +
* Try to interface everything and see if communication is reliable between the nodes. Do this early so that you can work on project requirements.
 +
 
 +
* Find out your motor PWM for forward, neutral and reverse as soon as you get the car. You can save time here.
 +
 
 +
* Simplify the wire connections to save time when you meet. When we met in the initial few weeks, most of the time was spent on connecting everything from scratch and figuring out why something is not working.
 +
 
 +
* Get good quality hardware so that you don't have to invest more time here.
  
 
=== Acknowledgement ===
 
=== Acknowledgement ===
 +
 +
We would like to thank our instructor, Preet, for all his efforts in our class and all motivation and guidance lifelong.  We have learnt so much about unit testing, C coding, software-hardware integration, team work, git and  documentation, all because of Preet.
 +
 +
We also have to acknowledge all the teams who came before us, their reports helped us a lot.
  
 
=== References ===
 
=== References ===

Latest revision as of 05:04, 20 May 2024

Project Title

Falcons



Abstract

The Falcon RC car project is the combined efforts of our team to create an autonomously RC Car that avoids all obstacles and follow GPS to reach the destination. Here, we have put in all our experience in software design, hardware design, unit testing, power systems, and mobile application development. Project development started in March of 2024 and ended in May 2024.

Introduction

The project was divided into 4 modules:

  • Sensor and Bridge Controller
  • Driver Controller
  • Geo Controller
  • Motor Controller

Driver controller is the master controller that receive inputs from sensor controller and geo controller, and gives output commands to motor controller. The destination coordinate is send from Android application to sensor node via Bluetooth. The app also send a hard start and stop to the car. The car starts only on receiving start signal from the app and stops completely on receiving stop signal from app.

Team Members & Responsibilities

<Team Picture>

Gitlab Project Link - https://gitlab.com/jincyjose491/sjtwo-c[1]


  • Sensor
    • Link to Gitlab user1
    • Link to Gitlab user2
  • Motor
    • Link to Gitlab user1
    • Link to Gitlab user2
  • Geographical
    • Link to Gitlab user1
    • Link to Gitlab user2
  • Communication Bridge Controller & LCD
    • Link to Gitlab user1
    • Link to Gitlab user2
  • Android Application
    • Link to Gitlab user1
    • Link to Gitlab user2
  • Testing Team
    • Link to Gitlab user1
    • Link to Gitlab user2


Schedule

Week# Start Date End Date Task Status
1 02/22/2024 02/26/2024
  • Literature survey- previous year project reports, hardware used, algorithms, challenges, advice to future students.
  • Ordered CAN transceivers.
Completed
2 02/26/2024 03/10/2024
  • Familiarize with the busmaster tool
  • Basic CAN tx, rx with DBC encode, decode
  • Discuss power management system
  • Compare sensors, RC cars, bluetooth modules and other relevant hardware.
  • Create project wiki page
  • Create a project schedule and updated wiki page
Completed
3 03/10/2024 03/12/2024
  • Create a block diagram for project
  • Finalize on roles
  • Finalize and order the list of selected components.
  • Create remote Git Lab repository
  • Establish a process for creating pull requests, code review and merging to master.
  • Discuss Android app design and development challenges
Completed
4 03/12/2024 03/19/2024
  • Write implementation for interfacing ultrasonic sensors with Sensor and Bridge Controller board along with Unit Tests
  • Write implementation for interfacing Bluetooth module with Sensor and Bridge Controller board along with Unit Tests
  • Write implementation for interfacing motor, steering and RPM module with Motor Controller board along with Unit Tests
  • Write implementation for interfacing GPS module with Geological Controller board along with Unit Tests
  • Write implementation for Interfacing magnetometer with Geological Controller board along with Unit Tests
  • Create dbc file for CAN communication
Completed
5 03/19/2024 03/26/2024
  • Bringup of ultrasonic sensors with SJ2 board-
    • Connect the sensor with the board using header connectors.
    • Check sensor functionality, obstacle detection.
    • Create initial draft for PCB design.
  • Bringup of bluetooth module with SJ2 board-
    • Connect the bluetooth module with the board using header connectors.
    • Check functionality, tx, rx, range.
    • Create initial draft for PCB design.
  • Bringup of motor controller with SJ2 board-
    • Disassemble the RC car, understand internal electrical connections, derive connections to control steering and drive the motor.
    • Control the steering and drive motor via SJ2 board.
    • Connect the encoder(RPM module) to the wheel and measure distance traveled.
    • Create initial draft for PCB design.
  • Bringup of GPS and Magnetometer module with SJ2 board-
    • Interface GPS module with SJ2 board and send data via CAN
    • Interface magnetometer with SJ2 board and send data via CAN
    • Create initial draft for PCB design.
  • Bring up of LCD with SJ2 board
    • Interface LCD with SJ2 board
    • Create initial draft for PCB design.
Completed
6 03/26/2024 04/02/2024
  • Bringup of entire system
    • Connect all the different modules together.
    • Validate CAN tx and rx among the modules.
    • Develop integration tests.
completed
7 04/02/2024 04/09/2024
  • Design and code initial draft of obstacle avoidance algorithm
  • Design and code initial draft of Android app
  • Finalize on power management
Completed
8 04/09/2024 04/16/2024
  • Prototype 1:
  • Integrate all HW with the custom designed PCB.
  • Validate initial draft of obstacle avoidance algorithm.
  • Validate initial draft of obstacle waypoint algorithm.
Not completed
9 04/16/2024 04/23/2024
  • Prototype 2:
  • Release and validate obstacle avoidance version 2
  • Release and validate waypoint algorithm version 2
  • Fine tune sensors for accuracy
  • Outdoor testing
Not completed
10 04/23/2024 04/30/2024
  • Prototype 3:
  • Release obstacle avoidance logic version 2
  • Release waypoint algorithm version 2
  • Outdoor testing version 2
Not completed
11 04/30/2024 05/07/2024
  • Final project demo
Not completed


Parts List & Cost

Item# Part Desciption Vendor Qty Cost
1 RC Car Traxxas 1 $265.00
2 SJ2 boards CMPE SCE 4 $50.00 each
3 CAN Transceivers Adafruit [2] 4 $3.95 each
4 Ultrasonic sensor Adafruit [3] 4 $114.00
5 GPS PA1616S BREAKOUT Digikey [4] 1 $29.95
6 LSM303AGR ACC COMPASS Digikey [5] 1 $12.50
6 LSM303AGR ACC COMPASS Digikey [6] 1 $12.50
7 LCD Display Amazon [7] 1 $12.99
8 RPM sensor Traxxas [8] 1 $12.00


Printed Circuit Board

<Picture and information, including links to your PCB>



CAN Communication

<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>




Sensor ECU

<Picture and link to Gitlab>

Hardware Design

Software Design

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

Technical Challenges

< List of problems and their detailed resolutions>



Motor ECU

<Picture and link to Gitlab>

Hardware Design

Software Design

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

Technical Challenges

< List of problems and their detailed resolutions>



Geographical Controller

Geo controller: https://gitlab.com/jincyjose491/sjtwo-c/-/tree/master/projects/geo_controller?ref_type=heads

Navigation in modern systems seamlessly integrates GPS with compass technology to enhance driving experience and safety. GPS provides accurate location data by communicating with satellites, while the compass offers directional orientation of the vehicle. This combination is essential also in the RC car project as it enables the vehicle to autonomously maneuver to a given detsination coordinate. The GPS modules keeps track of the current position of the car, provides the direction that the car should move towards and the compass module keeps track of the direction in which the car is actually heading. Integrating the two modules, an algorithm has been developed as elaborated below to achieve the complete autonomous functionality.

Hardware Design

The Geo controller is interfaced to both the GPS module and the compass modules. Both these modules are powered using stable 3.3V inputs which are derived from the SJ Two boards. The GPS communicates with the board via UART and is connected to the controller at the P4.28 and P4.29, Rx and TX pins respectively. The GPS requires an antenna which is interfaced to the module via a UFL to SMA connector. Though the GPS module houses an led to indicate FIX on GPS lock, the led3 of SJTwo board was used to also show lock acquired after GPS string was received. The compass module communicates with the board via I2C and is connected at P0.10 SDA and P0.11 SCL pins respectively. As part of the hardware design, the compass module was mounted on a separate long pole, away from other interferences. The led1 of SJTwo board was used to indicate a successful comapss read.


Compass module


GPS module


<Layout pic>

Software Design

The GPS module provides data in the form of NMEA strings. NMEA (National Marine Electronics Association) is a standard protocol used by GPS receivers to transmit data. These strings contain various pieces of information, such as latitude, longitude, altitude, and time. The data bytes sent from the GPS module through UART are first loaded into a line buffer. The algorithm then parses this buffer to capture the specific $GPGGA strings that includes the correct position, time, and fix status.

$GPGGA string parameters


Following is the GPS string parsing logic where the lattitude and longitude are retrieved:

static gps_coordinates_t gps_string_to_coordinates(char gps_line[line_buffer_size]) {
  gps_coordinates_t coordinates = {0, 0};
  char gps_line_copy[line_buffer_size];
  strcpy(gps_line_copy, gps_line);
  char *token = strtok(gps_line_copy, ",");
  int token_count = 0;
  char *tokens[6];
  while (token != NULL && token_count < 7) {
    if (token_count == 2 || token_count == 3 || token_count == 4 || token_count == 5 || token_count == 6) {
      tokens[token_count - 2] = token;
    }
    token = strtok(NULL, ",");
    token_count++;
  }

  // Check GPS Quality indicator value != 0 to see if FIX acquired
  if (strtof(tokens[4], NULL)) {
    GPS_fix_acquired = true;

    coordinates.latitude = strtof(tokens[0], NULL);
    char *latitude_dir = tokens[1];
    coordinates.longitude = strtof(tokens[2], NULL);
    char *longitude_dir = tokens[3];
    if (*latitude_dir == 'S')
      coordinates.latitude *= -1;
    if (*longitude_dir == 'W') {
      coordinates.longitude *= -1;
    }
  }
  return coordinates;
}

The compass module required calibration to provide accurate results. This was accomplished using MotionCal software, interfaced with an Arduino. After determining the hard and soft iron offsets, these values were applied in the code to perform software-based compass calibration. The compass heading relative to true north was then calculated based on the mounting direction. Proper register configuration was necessary to initialize the module and read the compass readings accurately.

Compass calibration

Following is the compass register settings for proper initialization:

void compass__init() {
  i2c__initialize(current_i2c, i2c_baudrate_hz, clock__get_peripheral_clock_hz(), &binary_semaphore_struct,
                  &mutex_struct);
  uint8_t ctrl_reg1_value = 0x8C;
  uint8_t ctrl_reg2_value = 0x02;
  uint8_t ctrl_reg3_value = 0x10;
  i2c__write_single(current_i2c, magnetometer_write, MAGNETOMETER_CTRL_REG1, ctrl_reg1_value);
  i2c__write_single(current_i2c, magnetometer_write, MAGNETOMETER_CTRL_REG2, ctrl_reg2_value);
  i2c__write_single(current_i2c, magnetometer_write, MAGNETOMETER_CTRL_REG3, ctrl_reg3_value);
}


Checkpoint Algorithm

The checkpoint algorithm finds the nearest checkpoint coordinate based on the current location among a series of checkpoints, considering also the distance to destination coordinates. Initially, it calculates the distance between the current location and the destination. Then, it iterates through each checkpoint, finding the distance from the current location to the checkpoint and from the checkpoint to the destination. If both distances are less than the minimum distance to the destination found so far, it updates the minimum distance and sets the next checkpoint accordingly. Finally, it returns the coordinates of the closest checkpoint considering the destination. This ensures proper navigation by selecting the most relevant checkpoint.

gps_coordinates_t find_closest_checkpoint_coordinate(gps_coordinates_t current_coordinate,
                                                     gps_coordinates_t destination_coordinate) {
  float min_distance_to_destination =
      coordinates__get_distance_to_destination(current_coordinate.latitude, current_coordinate.longitude,
                                               destination_coordinate.latitude, destination_coordinate.longitude);
  gps_coordinates_t next_checkpoint = destination_coordinate;

  for (uint8_t index = 0; index < max_checkpoints; index++) {
    float distance_to_waypoint =
        coordinates__get_distance_to_destination(current_coordinate.latitude, current_coordinate.longitude,
                                                 checkpoints[index].latitude, checkpoints[index].longitude);
    float distance_from_waypoint_to_destination =
        coordinates__get_distance_to_destination(checkpoints[index].latitude, checkpoints[index].longitude,
                                                 destination_coordinate.latitude, destination_coordinate.longitude);

    if (distance_to_waypoint < min_distance_to_destination &&
        distance_from_waypoint_to_destination < min_distance_to_destination) {
      min_distance_to_destination = distance_to_waypoint;
      next_checkpoint = checkpoints[index];
    }
  }
  return next_checkpoint;
}

Technical Challenges

As the geo logic came as the final step in the project, it could only be tested thoroughly after all other modules performed reliably. Several issues were identified and resolved on the geo controller side:

  • Problem: The compass was giving unreliable values and not pointing to true north.
    • Solution: The compass needed to be calibrated for the environment in which it was used, especially with the motor running.
  • Problem: The compass was giving a fixed range of values 170-250 dgrees, instead of the full 0-359 range, despite repeated calibrations.
    • Solution: The register configurations had to be updated. Specifically, the block data update needed to be set, and offset cancellation had to be enabled.
  • Problem: The GPS was giving no parsed outputs.
    • Solution: The issue was traced back to soldering errors. The TX and RX wires were not swapped correctly; the TX of the board needed to connect to the RX of the GPS module, and vice versa.
  • Problem: GPS was not acquiring stable lock inspite of testing it in open space and having the antenna connected.
    • Solution: A button cell was added to the GPS module in the slot (rear side) provided in the module which enabled it to acquire locks faster.
  • Problem: GPS parsing was incorrect and not returning proper data.
    • Solution: The line buffer size was increased, and it was ensured that a lock was obtained before reading the data.




Communication Bridge Controller & LCD

<Picture and link to Gitlab>

Hardware Design

Software Design

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

Technical Challenges

< List of problems and their detailed resolutions>



Driver Node

Gitlab Link: https://gitlab.com/jincyjose491/sjtwo-c/-/tree/master/projects/driver?ref_type=heads

LCD Display

Hardware Design

Driver node gives the interconnection between input and output. It receives input from geo node and sensor node and give commands to the motor node. The only hardware driver has is the LCD display and CAN transceiver. The LCD display used is a SunFounder IIC I2C TWI Serial 2004 20x4 LCD Module and is interfaced through an I2C bus through the I2C2 port. The module used and pin connections for LCD is shown below.

LCD Display
Table 6. LCD Display Pinout
SJTwo Board CAN Board
P0.11 SCL2
P0.10 SDA2
Vin 3.3
GND GND

Software Design

Driver has more software and less hardware. For navigation, there are two algorithms - obstacle avoidance and GPS navigation. Obstacle avoidance has precedence over GPS navigation. In case of any obstacle, car avoids obstacle. In other cases, it follows the path from geo node input. When the destination is reached, car slows down and stops.

Obstacle Avoidance

The obstacle avoidance code is written in the form of a truth table that has 4 bit input and one bit output. Inputs are four sensor values and output the motor commands. Bases on changes in sensor values, the motor command also changes. The logic that worked for us is given below

Table 6. Obstacle Avoidance Logic
left sensor right sensor middle sensor rear sensor motor command
0 0 0 X follow GPS navigation
0 1 0 X forward left
1 0 0 X forward right
0 1 1 0 reverse right
1 0 1 0 reverse left
X X 1 1 stop
1 1 0 0 reverse left

GPS Navigation

For GPS navigation the angle difference between heading and bearing is calculated and motor turn commands are generated based on this. Heading gives the current position in angle with respect to north. Bearing gives the angle to destination with respect to north. The logic that worked for our hardware is given below:

Table 6. GPS Logic
Angle difference = bearing - heading Turn Angle
0 to 180 left
180 to 360 right [angle = (360 - angle)]
-180 to 0 right
-360 to -180 left [angle = fabs(360 + angle)]

Technical Challenges

Since driver comes as the interconnect between all other nodes, the driver logic could be verified by outside testing only when we had stable input from geo and sensor node and motor nodes working as expected for given PWM. Unit testing can help in building of logic. But for actual test, we have to make sure all inputs are reliable. This can be verified with debug messages on bluetooth, CAN messages on busmaster, LCD display or LED indicators. The verification or debugging should be done in same frequency as which driver is processing.

  • Problem: LCD was not displaying anything.
    • Solution: Initially tried with 3.3V supply, then 5V supply and finally added level shifter to I2C pins. But the issue was slave address given in the datasheet was wrong. I got the correct slave address from web serial. After this was corrected, LCD worked well with 3.3V.
  • Problem: LCD flickered a lot when everything was connected together.
    • Solution: We initially connected all 5V supplies to a single 5V source. This included servo motor also. And it was causing the flicker. So, we powered up servo and rpm from ESC, all other sensors were powered separately from power bank and the issue was solved. This problem could have been avoided if more reports were read on how to power everything up.
  • Problem: Driver gave a reverse signal for one clock cycle when there was no obstacle.
    • Solution: Sensors gave random value for just one clock cycle and this caused driver to generate reverse command. After sensor inputs were corrected and made stable, the problem was solved.
  • Problem: Driver not able to correct turning commands to motor even after sensing obstacle on side. This happened in the clock cycle when there was obstacle on all three side and it took reverse.
    • Solution: We gave steps in angle changes in size of 5. Instead of direct 45 degree turn, car always turned in steps. So even though it sensed obstacle step sized turn angles took long clock cycles. So I finally reverted back to simple code logic of 45 degree turn and obstacle avoidance started working perfectly.
  • Problem: We thought driver was giving wrong commands to sensor values that was there on app.
    • Solution: Sensor values were updated at 1 Hz. Driver was working at 10Hz which is 10 times faster than what we see on app. So incorrect sensor value for just one cycle was not displayed. Finally debugged it in a hard way from all debugging sources listed above.


Mobile Application

<Picture and link to Gitlab>

Hardware Design

Software Design

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

Technical Challenges

< List of problems and their detailed resolutions>






Conclusion

<Organized summary of the project>

<What did you learn?>

Project Video

Project Source Code

Advise for Future Students

  • Make sure you have a clear idea on how to power up every modules in the project. This require careful distribution of power across the boards, sensors, motors. Connect everything together in the initial stage to see if entire module can work well when connected together. Doing this at an early stage helps to understand how to correctly power up everything. Again, you'll get an idea on which all modules should/should not be connected together, which module require additional power source, etc. from previous reports. Most of your problems could be solved from previous year reports. Don't limit yourself to 2-3 reports. Read more.. It'll be useful.
  • Try to interface everything and see if communication is reliable between the nodes. Do this early so that you can work on project requirements.
  • Find out your motor PWM for forward, neutral and reverse as soon as you get the car. You can save time here.
  • Simplify the wire connections to save time when you meet. When we met in the initial few weeks, most of the time was spent on connecting everything from scratch and figuring out why something is not working.
  • Get good quality hardware so that you don't have to invest more time here.

Acknowledgement

We would like to thank our instructor, Preet, for all his efforts in our class and all motivation and guidance lifelong. We have learnt so much about unit testing, C coding, software-hardware integration, team work, git and documentation, all because of Preet.

We also have to acknowledge all the teams who came before us, their reports helped us a lot.

References