S21: Roadster
Contents
Roadster
Abstract
Roadster is a battery powered autonomous car, that drives itself to a specified destination and avoids any obstacles that comes its way. The car infrastructure has four Nodes (Geo, Sensor, Driver and Motor) that communicate over the CAN bus and an android application interface to set the destination location. In order to make an informed decision the car processes Geo and Sensor Node’s data which is used to steer the car in the right direction.
Introduction
The project was divided into 5 modules:
- Sensor Node- Detecting obstacles in the vicinity of the car to avoid hitting the obstacle.
- Geo Node- Provide heading for car to reach destination. Communicate over blue tooth with mobile application.
- Driver Node- Manipulate turn angles and forward/reverse speed based on the inputs from Sensor and Geo nodes
- Motor Node- PID control logic to attain the said speed/direction desired by driver node.
- Android Application- Dashboard for real time data from car. Send instruction such as destination, way points and start/stop.
Team Members & Responsibilities
<Team Picture>
Tejas Pidwalkar
- Sensor Node
- Driver Node
Nimit Patel
- Geo Node
Tirth Pandya
- Motor Node
- PCB design
Srikar Reddy
- Android Application
Sourab Gupta
- Driver Node
<Provide ECU names and members responsible> <One member may participate in more than one ECU>
- Sensor Node
- Link to Gitlab user1
- Geo Node
- Link to Gitlab user1
- Driver Node
- Motor Node
- Link to Gitlab user1
- Android Application
- Link to Gitlab user1
Schedule
Week# | Start Date | End Date | Task | Actual Completion | Status |
---|---|---|---|---|---|
1
03/01 to 03/07 Start of Phase 1 |
|
|
|
|
|
2
03/08 to 03/14 |
|
|
|
|
|
3
03/15 to 03/21 |
|
|
|
|
|
4
03/22 to 03/28 |
|
|
|
|
|
5
03/29 to 04/04 End of Phase 1 |
|
|
|
|
|
6
04/05 to 04/11 Start of Phase 2 |
|
|
|
|
|
7
04/12 to 04/18 |
|
|
|
|
|
8
04/19 to 04/25 End of Phase 2 |
|
|
|
|
|
9
04/26 to 05/02 Start of Phase 3 |
|
|
|
|
|
10
05/03 to 05/09 |
|
|
|
|
|
11
05/10 to 05/16 End of Phase 3 |
|
|
|
|
|
Parts List & Cost
Item# | Part Desciption | Vendor | Qty | Cost |
---|---|---|---|---|
1 | RC Car | Traxxas [1] | 1 | $250.00 |
2 | CAN Transceivers MCP2551-I/P | Comimark [2] | 5 | $7.00 |
3 | Ultrasonic Sensors | Max Botix[3] | 5 | $150.00 |
4 | GPS and Antenna | Adafruit[4] | 1 | $60.00 |
5 | HC05 bluetooth RF Transreceiver | HiLetgo[5] | 1 | $12.59 |
6 | Triple-axis Accelerometer | Adafruit[6] | 1 | $21.40 |
7 | Traxxas RPM Sensor | Traxxas[7] | 1 | $12 |
8 | Discrete Electronic Components | Generic[8] | 1 | $28.75 |
9 | Buck-Boost Voltage Regulator | Generic[9] | 1 | $11.99 |
10 | Traxxas Telemetry Trigger magnet & holder | Traxxas[10] | 1 | $6.35 |
11 | Amazon[] | 1 | $ | |
12 | Amazon[] | 1 | $ | |
13 | Amazon[] | 1 | $ | |
14 | Amazon[] | 1 | $ |
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
Neighboring Sensor Interference:
As explained above, we have mounted three ultrasonic sensors in the front, and those were configured to range in continuous mode, in which sensors were continuously measuring distance by transmitting beam. Out of 3, the middle sensor is of type with wider beam to detect blind spots ahead.
Most of the time, we observed that the obstacle in the middle sensor range used also gets detected by the left/right sensor, which disturbs driving logic. This used to happen due to sensor beam interference among three sensors.
To solve this problem, we decided to trigger sensor beams in such time intervals that they won’t interfere with neighboring ones. We used the Rx pin of the sensor to trigger ranging and scheduled to trigger left and right sensor at one time and middle sensor next time. This sequence helped us avoid interference altogether.
< 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
Repository link for Geo Controller
Hardware Design
The SJ2 board communicates with:
- Bluettoth transreceiver over UART
- LSM303DLHC over I2C
- GPS model over UART
- Battery monitoring
Considering the orientation of the car changes as it travel along the land, tilt compensation logic for heading calculation using the magnetometer is a must for accurate measurement. Without the tilt compensation algorithm which uses the onboard accelorometer, the heading computation can have error up to 60 degrees, which has the potential to send the car off course.
For battery monitoring, the values for the voltage divider should be chosen such that the full range of the onboard ADC can be efficiently used. Depending one the cell type of the battery, the discharge curve can be use to map the charge state corresponding to voltage level. This method has its flaws and sophisticated techniques involving Coulomb count yields far better results, however, the technique discussed above suffices the needs of our project. Charge state of battery transmitted over Mobile app, greatly facilitates the charging schedule while testing and final demo day.
Software Design
The GEO controller is divided into 5 parts.
- The current location of the car is determined using the GPS.
- The current magnetic heading of car is determined using the on board compass.
- The way point calculation determines the nearest way point continuously by computing the distance using Haversine formula and current location using GPS.
- The heading is also computed using the Haversine formula and the difference between the actual and required is sent over the CAN bus for heading correction.
- Alternatively, once the car is within the threshold distance, next way point is selected and the car heads to the next way point.
Technical Challenges
- The GPS module sends data at 9600 baud rate, updating the data every one second. The data update rate needs to be updated to 10Hz for fast maneuvering and course correction of the car. If the update frequency is updated, the data sent over the UART is higher than it can handle in 10Hz periodic function. Hence, only GPGGA messages should be enabled to extract the required data and reduce the time spent in parsing the incoming string. NEMA (PMTK) messages should be correctly configured on the module for desired functioning.
- Heading calculation without the tilt compensation logic using the onboard accelorometer of LSM303 is in accurate. Reading accelorometer values requires and offset of 0x80 to the byte addressing of the accelorometer read. Magnetometer need no such offset. This is weird, considering both the I2C devices reside on the same physical chip.
- Using data type as float as opposed to double, utilizes the onboard FPU, which is faster. Double utilizes software implementation, which takes more clock cycle. Considering extensive use of math library in distance/heading measurement and tilt compensation algorithm, completing the task with the periodic is of at most importance.
- GPS fix is best when when there are no obstruction above the module. Module requires clear wide view of sky for a fast fix and error free location detection.
- LSM303DLHC is sensitive to even weak magnetic field interference. Place the chip devoid of such active/passive magnetic fields.
- Calibrating LSM303 is a must to get accurate heading values. 2-point calibration worked just fine for our team. More sophisticated methods are available too.
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
<Picture and link to Gitlab>
Hardware Design
Software Design
- Flow Chart
- Obstacle Avoidance Logic
- 1 Hz Loop:
- Transmit debug messages over the CAN bus
- 20 Hz Loop:
- Receive Sensor Data
- Receive Geo Data
- Process and Transmit Data(Motor Direction and Speed) to Motor Node
Technical Challenges
< List of problems and their detailed resolutions>
Mobile Application
<Picture and link to Gitlab> We created a lightweight mobile app to control our car, It can communicate with the car via Bluetooth and is capable of sending Destination co-ordinates along with checkpoints. Receive and Update live location on Google Maps, send Start, Stop and Clear commands, Receive and Display Debug Data.
Software Design
This app has mainly two activities, The main activity and maps activity.
Maps Activity
This is the only functional activity for the app and is responsible for the Google Maps and Bluetooth related Tasks. User can also dynamically select multiple checkpoints and send them to the bridge node. This is achieved using java vector and OnMapclickListener setup to read each marker placed by the user.
The Bluetooth connection is initially set up by reading the id and MAC addresses of the selected device, The available devices are displayed on a listView under the connect button. Bluetooth socket module provides read() and write() API used to communicate. Below is the code snippet that parses the incoming stream with location and debug data sent by the bridge node.
if(readMessage.indexOf("\n")>0) { message = new StringTokenizer(readMessage, "\n"); StringTokenizer st; while (message.hasMoreTokens()) { st = null; received_line = message.nextToken(); st = new StringTokenizer(received_line, ","); try { read = st.nextToken(); } catch (Exception e) { continue; } if (read.compareTo("GPS") == 0) { try { LatLng current_location = new LatLng(Double.parseDouble(st.nextToken()), Double.parseDouble(st.nextToken())); waypoint.setText(st.nextToken("\n").replace(",", "")); prev.remove(); prev = mMap.addMarker(new MarkerOptions().position(current_location).anchor(0.5f,0.5f).rotation(compass_value).title("Roadster") .icon(BitmapFromVector(getApplicationContext(), R.drawable.ic_baseline_directions_car_filled_24))); if (state || init) { mMap.moveCamera(CameraUpdateFactory.newLatLng(current_location)); if (current_location.latitude != 0) init = false; } } catch (Exception e) { } } else if (read.compareTo("speed") == 0) { try { speed.setText(st.nextToken("\n").replace(",", "") + "m/s"); } catch (Exception e) { } } else if (read.compareTo("sens") == 0) { try { left.setText(st.nextToken() + "cm"); right.setText(st.nextToken() + "cm"); center.setText(st.nextToken() + "cm"); back.setText(st.nextToken("\n").replace(",", "") + "cm"); } catch (Exception e) { } } else if (read.compareTo("comp") == 0) { try { compass.setText(st.nextToken()); String compass_s=st.nextToken("\n").replace(",", ""); compass_raw.setText(compass_s); compass_value =Integer.parseInt(compass_s); prev.setAnchor(0.5f,0.5f); prev.setRotation(compass_value); } catch (Exception e) { } } else if (read.compareTo("dist") == 0) { try { String dis=st.nextToken("\n").replace(",", ""); distance.setText(dis+"m"); //int prog=(int)Float.parseFloat(dis)%200; //progress.setProgress(prog); } catch (Exception e) { } } else if (read.compareTo("mot") == 0) { try { rps.setText(st.nextToken()); pwm.setText(st.nextToken("\n").replace(",", "")); } catch (Exception e) { } } else if(read.compareTo("bat")==0){ try{ battery.setText(st.nextToken("\n").replace(",", "")+"%"); }catch (Exception e){ } } } readMessage="";
Hardware 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?>
- Embedded project are generally single board projects. The mandatory use of CAN bus required a great deal of collaboration, where all board are interdependent and the system design should be robust to make it work every single time, the car is used for its intended purpose.
- Unit testing helps in early phase of the project, where the hardware setup is not ready yet, but one needs to start coding to get ahead of the curve and start building logic. This helps in troubleshooting the hardware as well.
Project Video
Project Source Code
Repository link for Autonomous RC Car
Advise for Future Students
- Get the hardware modules and test the same with SJ2 (Before the Mid Semester exams). Once this is done, create a PCB and mount devices and then start the extensive software testing. Considering the car is moving object, temporary connections over bread board and zero PCB might work, but reliability will remain a doubt at the back of the head. Eliminate the same by creating the PCB early. You might even want to iterate to a second PCB, once you are a few weeks into testing and want to change amend previous mistakes/improve existing layout and placements. The time and effort this will save is worth it.
- Once the hardware is nearing its completion, the Mobile app should be ready in its rudimentary form. Having a hand held debug device is more useful, compared to using PCAN dongle which is great for static testing.
- The software will take multiple iteration by testing your car in various field scenarios. This is not a project which can be completed a night before demo. Keep a healthy amount of time for testing.
- The sole working power socket available in university outside of the university buildings is available on the top floor of the tenth street car garage. This is especially useful when testing in field.
Acknowledgement
- Building a hardware project without the availability of a electronics lab of the university which had been shut, due to COVID-19 pandemic tested our resourcefulness to our extremes.Considering the remote nature of course work, resource availability in any shape or form from university was sadly non existent. All the team members should be appreciated for their unwavering enthusiasm to make this a success story.
- Preet's advice for buying quality hardware parts should be followed to the line.
=== References ===