S21: UTAH
Contents
- 1 UTAH: Unit Tested to Avoid Hazards
- 2 Abstract
- 3 Objectives & Introduction
- 4 Schedule
- 5 Parts List & Cost
- 6 Printed Circuit Board
- 7 Challenges
- 8 Printed Circuit Board
- 9 CAN Communication
- 10 Sensor ECU
- 11 Motor ECU
- 12 Servo Motor
- 13 Wheel encoder
- 14 Geographical Controller
- 15 Communication Bridge Controller & LCD
- 16 Master Module
- 17 Mobile Application
- 18 Conclusion
UTAH: Unit Tested to Avoid Hazards
Abstract
UTAH abstract
Objectives & Introduction
Show list of your objectives. This section includes the high level details of your project. You can write about the various sensors or peripherals you used to get your project completed.
Team Members & Responsibilities
- Akash Vachhani Gitlab
- Leader
- Geographical Controller
- Jonathan Beard Gitlab
- Android Application Developer
- Communication Bridge Controller
- Ameer Ali
- Master Controller
- Jonathan Tran Gitlab
- Sensors Controller
- Amritpal Sidhu
- Motor Controller
- Shreevats Gadhikar Gitlab'
- Motor Controller
Schedule
Description | Color |
---|---|
Administrative | Black |
Sensor | Cyan |
Bluetooth & App | Blue |
GEO | Red |
Motor | Magenta |
Main | Orange |
Week# | Start Date | End Date | Task | Status |
---|---|---|---|---|
1 |
|
|
|
|
2 |
|
|
|
|
3 |
|
|
|
|
4 |
|
|
|
|
5 |
|
|
|
|
6 |
|
|
|
|
7 |
|
|
|
|
8 |
|
|
|
|
9 |
|
|
|
|
10 |
|
|
|
|
11 |
|
|
|
|
12 |
|
|
|
|
13 |
|
|
|
|
14 |
|
|
|
|
Parts List & Cost
Item# | Part Description | Vendor | Qty | Cost |
---|---|---|---|---|
1 | Traxxas 1/10 Scale RC Short Truck | Traxxas [1] | 1 | $239.99 + Tax |
2 | RPM Sensor & Mount | Traxxas [2] | 1 | $19.00 + Tax |
3 | 2S 7.4V 5000mAh LiPo Battery Pack | Amazon [3] | 2 | $40.69 + Tax |
4 | Bluetooth Adapter | Amazon [4] | 1 | $8.99 + Tax |
5 | Adafruit Ultimate GPS Breakout | Adafruit [5] | 1 | $39.95 |
6 | Adafruit Triple-axis Accelerometer+Magnetometer | Adafruit [6] | 1 | $14.95 |
7 | Deans Connector | Amazon [7] | 1 | $8.99 + Tax |
8 | Pololu 5V Voltage Regulator | Pololu [8] | 1 | $10.83 |
9 | PCB | JLCPCB [9] | 1 | $40.00 |
Printed Circuit Board
<Picture and information, including links to your PCB>
We started with a very basic design for our Rc car on a breadboard. All the components were integrated on the breadboard for testing purposes.
Challenges
The wirings on the breadboard succeed on the first attempt but later when we kept adding the components as per the requirements the wiring became a complete mess and was entangling everywhere due to which the car could not navigate properly. Every time the car collided, the wires used to get disconnected. So we decided to go with PCB.
Printed Circuit Board
To overcome all the challenges which were faced on the breadboard we designed the PCB on EasyEDA. EasyEDA allows the creation and editing of schematic diagrams, and also the creation and editing of printed circuit board layouts and, optionally, the manufacture of printed circuit boards. So we implemented the custom PCB using EasyEDA Software in which we implemented all the four controller connections. The four controllers included Master Controller, Geo Controller, Sensor Controller, and Motor Controller. The communication of these four controller was via a CAN bus.
CAN Communication
<Talk about your message IDs or communication strategy, such as periodic transmission, MIA management etc.>
Our message IDs were chosen based upon an agreed priority scheme. We assigned high priority IDs to messages that controlled the movement of the car, followed by sensor and GEO messages, and lowest priority messages were for debug and status.
Debug and status messages were sent in the 1Hz, and a few in the 10Hz, callbacks. The sensor and driver boards send data at the fastest rate (20Hz), so receiving all messages is done at 20Hz as well.
Each board managed MIAs using the auto generated API. Each board received all messages in one function call, and the service MIA function would be executed if messages a board was expecting did not arrive. The increment and threshold values for MIA were in units of milliseconds, so it was easy to adjust threshold values if we wanted a MIA to occur earlier or later.
Hardware Design
<Show your CAN bus hardware design>
DBC File
VERSION "" NS_ : BA_ BA_DEF_ BA_DEF_DEF_ BA_DEF_DEF_REL_ BA_DEF_REL_ BA_DEF_SGTYPE_ BA_REL_ BA_SGTYPE_ BO_TX_BU_ BU_BO_REL_ BU_EV_REL_ BU_SG_REL_ CAT_ CAT_DEF_ CM_ ENVVAR_DATA_ EV_DATA_ FILTER NS_DESC_ SGTYPE_ SGTYPE_VAL_ SG_MUL_VAL_ SIGTYPE_VALTYPE_ SIG_GROUP_ SIG_TYPE_REF_ SIG_VALTYPE_ VAL_ VAL_TABLE_ BS_: BU_: DBG DRIVER IO MOTOR SENSOR GEO BO_ 100 BRIDGE_APP_COMMANDS: 1 SENSOR SG_ APP_COMMAND : 0|2@1+ (1,0) [0|0] "" GEO,DRIVER BO_ 101 MOTOR_CHANGE_SPEED_AND_ANGLE_MSG: 2 DRIVER SG_ DC_MOTOR_DRIVE_SPEED_sig : 0|8@1+ (0.1,-10) [-10|10] "kph" MOTOR SG_ SERVO_STEER_ANGLE_sig : 8|8@1+ (1,-45) [-45|45] "degrees" MOTOR BO_ 102 SENSOR_SONARS_ROUTINE: 5 SENSOR SG_ SENSOR_SONARS_left : 0|10@1+ (1,0) [0|0] "inch" DRIVER SG_ SENSOR_SONARS_right : 10|10@1+ (1,0) [0|0] "inch" DRIVER SG_ SENSOR_SONARS_middle : 20|10@1+ (1,0) [0|0] "inch" DRIVER SG_ SENSOR_SONARS_rear : 30|10@1+ (1,0) [0|0] "inch" DRIVER BO_ 300 GPS_DESTINATION_LOCATION: 8 SENSOR SG_ DEST_LATITUDE : 0|32@1+ (0.000001,-90.000000) [-90|90] "Degrees" GEO SG_ DEST_LONGITUDE : 32|32@1+ (0.000001,-180.000000) [-180|180] "Degrees" GEO BO_ 301 COMPASS_HEADING_DISTANCE: 6 GEO SG_ CURRENT_HEADING : 0|12@1+ (0.1,0) [0|359.9] "Degrees" DRIVER,SENSOR SG_ DESTINATION_HEADING: 12|12@1+ (0.1,0) [0|359.9] "Degrees" DRIVER,SENSOR SG_ DISTANCE : 24|17@1+ (0.01,0) [0|0] "Meters" DRIVER,SENSOR BO_ 501 GPS_CURRENT_INFO: 8 GEO SG_ GPS_CURRENT_LAT : 0|32@1+ (0.000001,-90.000000) [-90|90] "degrees" DRIVER,SENSOR,MOTOR SG_ GPS_CURRENT_LONG : 32|32@1+ (0.000001,-180.000000) [-180|180] "degrees" DRIVER,SENSOR,MOTOR BO_ 502 GPS_COMPASS_STATUS : 1 GEO SG_ COMPASS_LOCK_VALID: 0|1@1+ (1,0) [0|0] "TRUE_FALSE" DRIVER, SENSOR SG_ GPS_LOCK_VALID : 1|1@1+ (1,0) [0|0] "TRUE_FALSE" DRIVER,SENSOR,MOTOR BO_ 503 GPS_CURRENT_DESTINATIONS_DATA: 8 GEO SG_ CURRENT_DEST_LATITUDE : 0|32@1+ (0.000001,-90.000000) [-90|90] "Degrees" DRIVER SG_ CURRENT_DEST_LONGITUDE : 32|32@1+ (0.000001,-180.000000) [-180|180] "Degrees" DRIVER BO_ 504 RC_CAR_SPEED_READ_MSG: 2 MOTOR SG_ RC_CAR_SPEED_sig : 0|8@1+ (0.1,-10) [-10|10] "kph" DRIVER,SENSOR BO_ 750 DBG_RAW_COMPASS_DATA: 4 GEO SG_ SIGNED_REGISTER_VAL_MAG_X : 0|16@1+ (1.0,0) [-2048|2047] "GAUSSIAN" DRIVER,SENSOR SG_ SIGNED_REGISTER_VAL_MAG_Y : 16|16@1+ (1.0,0) [-2048|2047] "GAUSSIAN" DRIVER,SENSOR BO_ 751 DBG_CONFIRM_RECEIVED_DESTINATION: 8 GEO SG_ RECEIVED_DEST_LATITUDE : 0|32@1+ (0.000001,-90.000000) [-90|90] "Degrees" SENSOR SG_ RECEIVED_DEST_LONGITUDE : 32|32@1+ (0.000001,-180.000000) [-180|180] "Degrees" SENSOR BO_ 775 DBG_GPS_COMPASS_LOCK_LED_CHECK: 1 GEO SG_ COMPASS_LED_STATUS: 0|1@1+ (1,0) [0|0] "TRUE_FALSE" DRIVER, SENSOR, MOTOR SG_ GPS_LED_STATUS : 1|1@1+ (1,0) [0|0] "TRUE_FALSE" DRIVER, SENSOR, MOTOR BO_ 780 DBG_GEO_CAN_STATUS: 3 GEO SG_ DBG_CAN_INIT_STATUS: 0|1@1+ (1,0) [0|0] "TRUE_FALSE" DRIVER, SENSOR, MOTOR SG_ DBG_CAN_RX_DROP_COUNT : 1|16@1+ (1,0) [0|0] "TRUE_FALSE" DRIVER,SENSOR,MOTOR BO_ 781 DBG_SENSOR_CAN_STATUS: 3 SENSOR SG_ DBG_CAN_INIT_STATUS: 0|1@1+ (1,0) [0|0] "TRUE_FALSE" DRIVER, GEO, MOTOR SG_ DBG_CAN_RX_DROP_COUNT : 1|16@1+ (1,0) [0|0] "drops" DRIVER,GEO,MOTOR BO_ 782 DBG_MOTOR_CAN_STATUS: 3 MOTOR SG_ DBG_CAN_INIT_STATUS: 0|1@1+ (1,0) [0|0] "TRUE_FALSE" DRIVER, SENSOR, GEO SG_ DBG_CAN_RX_DROP_COUNT : 1|16@1+ (1,0) [0|0] "TRUE_FALSE" DRIVER,SENSOR,GEO BO_ 783 DBG_DRIVER_CAN_STATUS: 3 DRIVER SG_ DBG_CAN_INIT_STATUS: 0|1@1+ (1,0) [0|0] "TRUE_FALSE" GEO, SENSOR, MOTOR SG_ DBG_CAN_RX_DROP_COUNT : 1|16@1+ (1,0) [0|0] "TRUE_FALSE" GEO,SENSOR,MOTOR BO_ 784 DBG_MOTOR_INFO_MSG: 4 MOTOR SG_ DBG_DC_MOTOR_CURRENT_PWM_sig: 0|8@1+ (0.1,0) [10|20] "duty percent" DRIVER SG_ DBG_SERVO_MOTOR_CURRENT_PWM_sig : 8|8@1+ (0.1,0) [10|20] "duty percent" DRIVER SG_ DBG_PID_OUTPUT_VALUE_sig : 16|8@1+ (0.1,0) [0|0] "kph" DRIVER SG_ DBG_MOTOR_SELF_TEST_sig : 24|1@1+ (1,0) [0|0] "TRUE_FALSE" DRIVER BO_ 001 DRIVER_HEARTBEAT: 1 DRIVER SG_ DRIVER_HEARTBEAT_cmd : 0|8@1+ (1,0) [0|0] "" SENSOR,MOTOR BO_ 002 SENSOR_HEARTBEAT: 1 SENSOR SG_ DRIVER_HEARTBEAT_cmd : 0|8@1+ (1,0) [0|0] "" SENSOR,MOTOR BO_ 003 GEO_HEARTBEAT: 1 GEO SG_ DRIVER_HEARTBEAT_cmd : 0|8@1+ (1,0) [0|0] "" SENSOR,MOTOR BO_ 004 MOTOR_HEARTBEAT_MSG: 1 MOTOR SG_ MOTOR_HEARTBEAT_sig : 0|8@1+ (1,0) [0|255] "pulse" DRIVER CM_ BU_ DRIVER "The driver controller driving the car"; CM_ BU_ MOTOR "The motor controller of the car"; CM_ BU_ SENSOR "The sensor controller of the car"; CM_ BO_ 100 "Sync message used to synchronize the controllers"; CM_ SG_ 100 DRIVER_HEARTBEAT_cmd "Heartbeat command from the driver"; BA_DEF_ "BusType" STRING ; BA_DEF_ BO_ "GenMsgCycleTime" INT 0 0; BA_DEF_ SG_ "FieldType" STRING ; BA_DEF_DEF_ "BusType" "CAN"; BA_DEF_DEF_ "FieldType" ""; BA_DEF_DEF_ "GenMsgCycleTime" 0; BA_ "GenMsgCycleTime" BO_ 100 1000; BA_ "GenMsgCycleTime" BO_ 200 50; BA_ "FieldType" SG_ 100 DRIVER_HEARTBEAT_cmd "DRIVER_HEARTBEAT_cmd"; VAL_ 100 DRIVER_HEARTBEAT_cmd 2 "DRIVER_HEARTBEAT_cmd_REBOOT" 1 "DRIVER_HEARTBEAT_cmd_SYNC" 0 "DRIVER_HEARTBEAT_cmd_NOOP" ;
Sensor ECU
<Picture 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
Motor Controller includes the controlling of the DC motor, Servo motor, Electronic speed control (ESC), and the wheel encoder. The job of the motor controller is both to steer and spin the wheels in order to move the RC car to the target destination. The DC motor, servo motor, and ESC(Traxxas ESC XL-05) were provided with the Traxxas RC car. The wheel encoder was purchased separately from Traxxas's website. The job of the DC motor is to control the spinning of the rear 2 wheels through the utilization of ESC and wheel encoder whereas the job of the servo motor is to control the steering of the front 2 wheels.
SJ2 Board Pin | Description |
---|---|
5V | Input power |
3.3V | CAN transceiver power |
PWM2 P2.1 | DC Motor Speed Control |
PWM5 P2.4 | Servo Motor Control |
CAP0 P2.6 | Input Capture for RPM Sensor |
CAN1 TX | CAN Module Tx |
CAN1 RX | CAN Module Rx |
GND | Grounding |
DC Motor and ESC
The DC motor and ESC were provided with RC car. The DC motor is controlled by the ESC using PWM signals which were provided by the motor controller board for forward, neutral, and reverse movements. The ESC is powered ON using a 7.4 LiPo battery. The ESC converts this 7.4V to 6V and provides input to DC Motor.
ESC wires | Description | Wire Color |
---|---|---|
Vout | Output Power (6V) | RED |
GND | Ground | BLACK |
PWM | PWM input from SJ2-Board (P2.1) | WHITE |
The car can be operated at 100Hz in the following 3 modes :
Sport Mode (100% Forward, 100% Brakes, 100% Reverse)
Racing Mode (100% Forward, 100% Brakes, No Reverse)
Training Mode (50% Forward, 100% Brakes, 50% Reverse)
Servo Motor
...
Wheel encoder
For speed sensing we purchased a Traxxas RPM sensor as it mounted nicely in the gear box. The RPM sensor works by mounting a magnet to the spur gear and a hall effect sensor fixed to the gear box. To get the revolutions per second we used Timer2 as an input capture.
...
Software Design
The motor controller code consisted of 3 main parts, which are: 1. PWM driver and motor logic, 2. RPM sensor, 3. PID controller.
1. PWM driver and motor logic
The PWM drivers were fairly easy to write since the SJ2 project provided an API for the low level function calls. Converting speed and angle values to duty cycle values was done by simply linearly mapping one onto the other. This worked fine for steering control, but due to varying grades the car needs to drive on, the PID is needed. The Traxxas ESC, as other students have discovered in the past, has safeguards to prevent damage to the motor by not allowing duty cycle to abruptly change, from a forward signal to a reverse. The Traxxas controller uses a trigger for this, but as other students suggested, we used a state machine to transition into opposite direction. We found that going from reverse to forward simply requires stopping (15% duty cycle) the car first, while going from forward to reverse required sending the following signals: STOP, REVERSE, STOP, REVERSE. Since we did not consult with Traxxas, this logic was created through trial and error. Transitioning into the opposite direction might simply just require stopping first, and then delay until a speed is reached, then change directions. We had access to an oscilloscope, however we did not capture what actually happens to the DC motor duty cycle when the transmitter does the same transition.
2. RPM sensor
To count the time interval between pulses the RPM sensor makes, we used one of the LPC's peripheral timers that allowed for an input capture feature. We configured the hardware registers such that a capture register is written the value of the timer count register when the input capture (pulse from RPM sensor) occurs. This required writing a low level API so that we could unit test the hardware reading and writing. An interrupt also triggers on a capture event to reset the timer counter, to make the value in the capture register easy to convert to revolutions per second. The circumference of the car's tire and spur gear ratio are needed to determine a scalar value to convert the revolutions per second to conventional speed units. Many students said the RPM sensor from Traxxas was inconsistent and unreliable for speed feedback. We thought that this might be because of how the sensor is measuring the speed of the spur gear and that the differential of the car might cause variation, however when the car goes in a straight line that should not be a problem. When we integration tested the software design with the PID using the above approach, the speed readings seemed stable enough for use with the PID.
3. PID controller
For situations where the DC motor needs to do more or less work (e.g. driving uphill or downhill) the linear mapping will not work. The proportional, integral, derivative (PID) controller is a widely used control mechanism to ensure a machine maintains a set point. In discrete time the integration becomes a summation and the derivative becomes a difference. The controller is based on an error from the set point, which is why the RPM sensor is needed to get feedback. The PID algorithm is fairly simple, as is tuning the gains. We found that the proportional and integral gains were enough to get the car to maintain speed.
Below is our design for the periodic callbacks.
Periodic Callbacks Initialize:
- Initialize:
- CAN bus
- DC motor PWM
- Servo motor PWM
- RPM sensor input capture
- PID
- Motor logic
Periodic Callbacks 1Hz
- Reset CAN bus if bus goes off
- Have LED indicate CAN bus running status
- Transmit motor debug message
- Transmit motor CAN status
Periodic Callbacks 10Hz
- At 2Hz transmit motor speed
- Run motor self-test on start up
- Once done control motor's based on CAN messages
Periodic Callbacks 100Hz
- At 20Hz receive all messages from CAN bus
- Update local global variable if motor message received
Technical Challenges
- Getting the state machine right for the DC motor to transition between forward and backwards, and vice versa, took some experimentation. Luckily other student's reports were available for us to have a hint on what we needed to do.
- When first tuning the PID our boards were attached via jumper wires and breadboard on a piece of plexiglass. The plexiglass was not rigidly secured to the car either, which resulted in collisions with walls and wires becoming undone. All this led to more hardware issues and had us backtrack to get the PID tuned. Making sure the hardware is sound before doing full integration tests will save you time. This requires planning out the hardware early on, and preferably just getting a PCB manufactured.
- We were having problems during integration testing where the motors would not run. It's hard to say what the solution was for certain, but slowing down the rate we updated the PWMs (from 20Hz to 10Hz) seemed to be it.
- We damaged the ESC somehow and needed to purchase another. This cost us time and money. Make sure you don't accidentally short the ESC!
- Some unit tests were not written until after integration testing. This goes against test driven development, but due to deadlines we had to make a choice. Had we thought out the use cases of our modules and wrote unit tests sooner, I'm sure we would have avoided some in the field debugging.
- The code had to be redesigned for modularity and readability later on. Make sure to avoid software anti-patterns, like "blob," and use dependency injection to prevent tightly coupled code modules.
Geographical Controller
<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>
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>
Master Module
<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>
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
<Bullet points and discussion>