S24: Team X

From Embedded Systems Learning Academy
Revision as of 21:02, 12 May 2024 by 243 user3 (talk | contribs) (Software Design)

Jump to: navigation, search

Project Title

Team X



Abstract

Our main goal of this project was to utilize the knowledge acquired from the lectures in CMPE 243. The report summarizes the overall process taken to develop an autonomous driving RC car using FreeRTOS, various periodic tasks, and the CAN bus to combine and run the different code modules.

Introduction

The project was divided into 5 modules:

  • Sensor Node
  • Motor Node
  • Driver Node
  • Geo Node
  • Mobile Application

Team Members & Responsibilities

<Team Picture>

Gitlab Project Link [1]


Team Members Task Responsibility
  • Priyanka Shah
  • Geo Controller, Mobile App
  • Faaris Khilji
  • Sensor and Bridge Controller
  • Ashley Ho
  • Driver and LCD Controller
  • All/TBD
  • Motor Controller




Schedule

Week# Start Date End Date Task Status
1 02/19/2024 02/25/2024
  • Read previous projects, gather information, and discuss among the group members.
  • Schedule weekly online meetings
  • Order CAN transceivers
  • Test GPS and UART communication.
  • Completed
  • Completed
  • Completed
2 02/26/2024 03/03/2024
  • Distribute modules to each team member.
  • Create parts list and Bill of Materials
  • Test CAN Bus communication between 2 boards
  • Completed
  • Completed
  • Completed
3 03/04/2024 03/11/2024
  • Order all sensors
  • Research on RC car brands and features.
  • Create project schedule and milestones.
  • Completed
  • Completed
  • Completed
4 03/18/2024 03/24/2024
  • Setup project repository
  • Order RC car
  • Test CAN bus with DBC file messages via BusMaster
  • Completed
  • Completed
  • Completed
5 03/25/2024 03/31/2024
  • Set up driver node to handle CAN messages received from sensor node
  • Set up sensor node to send CAN messages
  • Set up motor controller node to receive driver commands
  • Completed
  • Completed
  • Completed
6 04/01/2024 04/07/2024
  • Set up Geo Controller to receive destination coordinates
  • Link Geo controller to GPS module
  • Integrate sensor hardware into sensor node
  • Test LCD module to display using I2C
  • Begin wiki documentation
  • Completed
  • Completed
  • Completed
  • Completed
  • Completed
7 04/08/2024 04/14/2024
  • Enhance obstacle avoidance algorithm
  • Integrate RPM and ultrasonic sensor
  • Integrate LCD module with debug messages
  • Setup preliminary mobile app structure
  • Test obstacle avoidance
  • Start working on power supply for SJ2 boards
  • Completed
  • Completed
  • Completed
  • Completed
  • Completed
  • Completed
8 04/15/2024 04/21/2024
  • Fine tune obstacle avoidance algorithm
  • Hack RC car's RPM and install RPM sensor
  • Integrate compass module
  • Begin RC car design and assembly
  • Completed
  • Completed
  • In Progress
  • Completed
9 04/22/2024 04/28/2024
  • Finish RC car prototype 1
  • Start outdoor testing at garage rooftop
  • Complete basic mobile app with destination, start/stop buttons
  • Interface motor and steering
  • Set up LED fault indicators
  • Completed
  • Completed
  • In Progress
  • Completed
  • Completed
10 04/29/2024 05/05/2024
  • Edit Wiki report, continue updating through next few weeks
  • Fine tune mobile app to display real-time location
  • Display debug information on LCD
  • Implement PID controller
  • Continue RC outdoor tests
  • In Progress
  • In Progress
  • Completed
  • In Progress
  • Completed
11 05/06/2024 05/12/2024
  • Fine tune obstacle avoidance algorithm
  • Fine tune motor controller and sensor controller
  • Fine tune DBC file messages
  • Continue updating wiki report and documentation
  • Completed
  • Completed
  • Completed
  • Completed
12 05/06/2024 05/12/2024
  • Tidy RC car mounted hardware
  • Continue outdoor testing
  • Fine tune navigational system
  • In Progress
  • Completed
  • Completed
13 05/13/2024 05/19/2024
  • Finish writing project report
  • Final RC car tests on North Garage
  • Reimburse team members for RC car parts and sensors
  • Incomplete
  • Incomplete
  • Incomplete
14 05/20/2024 05/26/2024
  • Final Project Demos
  • Incomplete


Parts List & Cost

Item# Part Desciption Vendor Qty Cost
1 RC Car Traxxas 1 $250.00
2 RC Car Battery Traxxus 2 $100
3 CAN Transceivers MCP2551-I/P Microchip [2] 8 Free Samples
4 MB1010 LV-MaxSonar <Insert Company> 4 $29.95
5 GPS <Insert Company> <Insert Amount> <Insert Price>
6 Compass <Insert Company> <Insert Amount> <Insert Price>
7 LCD <Insert Company> <Insert Amount> <Insert Price>


CAN Communication

Each node is connected to a CAN transceiver that are connected to a bus with a 120 Ohm resistor on each end. We handled each message on the 10Hz, with the sensor and motor messages having the highest priority.

Specifically, we classified each node with these (see table below) message IDs.

Node Message ID Range
1 MOTOR 300 - 310
2 SENSOR 200
3 GEO 400 - 450
4 DEBUG 700

Hardware Design

Can.drawio.png

DBC File

Gitlab DBC File Link [3]




Sensor and Bridge Controller ECU

<Picture>

Gitlab Sensor and Bridge Controller Node Link [4]

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>

Gitlab Motor Node Link [5]

Hardware Design

Software Design

The motor software takes in driver-motor commands through the CAN bus and based on those commands, modifies the PWMs of the motor and the servo to move the wheels forward, backward, left, or right. We mapped the PWM values as seen in the table below:

Motor PWM Direction
1 16.2 Forward
2 14.5 Backward
3 15.02 Idle
Servo PWM Direction
1 11.0 Hard Left
2 13.0 Slight Left
3 15.48 Straight
4 17.0 Slight Right
5 19.0 Hard Right
void motor_pwm__set_pwm(void) {
  motor_pwm__set_motor_pwm();
  motor_pwm__set_servo_pwm();
}


static void motor_pwm__set_servo_pwm(void) {
  static float set_servo_duty_cycle = servo_pwm_idle_duty_cycle;

  if (motor_cmd_local.MOTOR_CMD_steer == 0) {
    // idle
    set_servo_duty_cycle = servo_pwm_idle_duty_cycle;
  } else if (motor_cmd_local.MOTOR_CMD_steer == 1) {
    // slightly right
    set_servo_duty_cycle = 17.00;
  } else if (motor_cmd_local.MOTOR_CMD_steer == 2) {
    // max right
    set_servo_duty_cycle = 19.00;
  } else if (motor_cmd_local.MOTOR_CMD_steer == -1) {
    // slightly left
    set_servo_duty_cycle = 13.00;
  } else if (motor_cmd_local.MOTOR_CMD_steer == -2) {
    // max left
    set_servo_duty_cycle = 11.00;
  }

  pwm1__set_duty_cycle(servo_pwm, set_servo_duty_cycle);
}


static void motor_pwm__set_motor_pwm(void) {
  static float set_motor_duty_cycle = motor_pwm_idle_duty_cycle;

  if (motor_stop_local.MOTOR_STOP_stop) {
    motor_speed_pid_set_target_pwm(motor_pwm_idle_duty_cycle);
  } else {
    if (!ignore_cmds) {
      if (motor_cmd_local.MOTOR_CMD_forward == -1) { // Reverse
        set_motor_duty_cycle = 14.50;
        if (reverse_flag == false) {
          motor_speed_pid_set_target_pwm(motor_pwm_idle_duty_cycle);
          ignore_cmds = true;
          start_time = sys_time__get_uptime_ms();
          reverse_flag = true;
          return;
        }
      } else if (motor_cmd_local.MOTOR_CMD_forward == 0) { // Stop
        set_motor_duty_cycle = motor_pwm_idle_duty_cycle;
      } else if (motor_cmd_local.MOTOR_CMD_forward == 3) { // Forward
        set_motor_duty_cycle = 16.2;                       // 15.7 originally?, 16.2

        if (reverse_flag == true) {
          motor_speed_pid_set_target_pwm(motor_pwm_idle_duty_cycle);
          ignore_cmds = true;
          start_time = sys_time__get_uptime_ms();
          reverse_flag = false;
          return;
        }
      }
      motor_speed_pid_set_target_pwm(set_motor_duty_cycle);
    } else if (sys_time__get_uptime_ms() - start_time >= DIRECTION_CHANGE_DELAY) {
      ignore_cmds = false;
    } else {
    }
  }
}


Technical Challenges

< List of problems and their detailed resolutions>

The main issue we had with the motor controller occurred during PWM hacking because we did not want the motor running the car too fast. As such, we had to guess and check a good PWM value to run the motor so that the car would move at the slowest speed possible without running into issues where it could not move. However, with continual tests, we managed to identify the ideal range we wanted to run the motor.



Geographical Controller

<Picture>

Gitlab Geo Node Link [6]

Hardware Design

Software Design

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

Technical Challenges

< List of problems and their detailed resolutions>



Driver and LCD Module

Gitlab Driver & LCD Node Link [7]

Hardware Design

The driver node, aside from its connection to the CAN bus, is also connected the the LCD module through I2C. the SJ2 board provides the LCD with 3.3V power and sends data through SDA and SCL.

DriverLCD.png

Software Design

The driver logic came down to a basic logic (show in table below) where 0 implies there is no obstacle, and 1 implies an obstacle is present.

Driverlogic.png

dbc_MOTOR_CMD_s driver__get_motor_commands(void) {
  driver__avoid_obstacle();
  return motor_commands;}


static void driver__avoid_obstacle(void) {
  obstacle_below_threshold_s below_thresholds = driver__closest_obstacle();

  if (!(below_thresholds.MIDDLE) && !(below_thresholds.LEFT) && !(below_thresholds.RIGHT)) {
    driver__go_to_destination();
  } else {
    driver__steering();
  }
  driver__led_indicators();}


dbc_MOTOR_CMD_s driver__get_motor_commands(void) {
  driver__avoid_obstacle();
  return motor_commands;}


// slight turns for destination movement
static void driver__go_to_destination(void) {
  int angle_difference = local_geo_status.GEO_STATUS_COMPASS_HEADING - local_geo_status.GEO_STATUS_COMPASS_BEARING;
  if (local_geo_status.GEO_STATUS_DISTANCE_TO_DESTINATION > 0) {
    if (angle_difference > 0) {
      // go right
      motor_commands.MOTOR_CMD_steer = 1;
      motor_commands.MOTOR_CMD_forward = 3;
    } else if (angle_difference < 0) {
      // go left
      motor_commands.MOTOR_CMD_steer = -1;
      motor_commands.MOTOR_CMD_forward = 3;
    } else { // go straight
      motor_commands.MOTOR_CMD_steer = 0;
      motor_commands.MOTOR_CMD_forward = 3;
    }
  } else { // reached destination
    motor_commands.MOTOR_CMD_forward = 0;
    motor_commands.MOTOR_CMD_steer = 0;
  }}


Technical Challenges

Most of the issues surrounding the driver node occurred after field testing. We found there were some issues regarding how soon the driver made the decision compared to when it received the sensor data. As such, we made adjustments so that, despite the delay, there would be time for the driver to receive the sensor data, identify the correct action to take, and then move the wheels. Overall, our driver node worked as expected once we started field testing due to the multitude of unit tests that were done to ensure proper logic.

Additionally, we ran into issues integrating the LCD screen through I2C. The screen's slave address would not get detected, despite the device having the proper connections and power supply. However, it was found to have just been a hardware issue and worked with a different I2C LCD device.



Mobile Application

<Picture and link to Gitlab>

Gitlab Mobile APp Node Link [8]

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

Team X Gitlab Link [9]

Advice for Future Students

  • Start early! Order things as soon as you have your team, and keep track of finances for reimbursements

Acknowledgement

Thank you Preet for the class and for guiding us through the process of building the RC car.

References

1. LCD Datasheet
2. LCD Display Initialization and Configuration Example Tutorial