Comma.ai is one of the few respectable tech companies offering one of the most advanced self-driving products: the comma 3x. - Automates ~70+% of daily driving. - Performs exceptionally well on highways and other roads with identifiable lanes. - Installed and mounted on a car’s front windshield, so it can receive a live data feed of the road. - Using this live feed, the comma 3x projects the path for the vehicle to follow.
Comma API
Comma uploads driving data to its servers to train better models and improve the self-driving experience over time. We can access our driving data using the comma API. Using our driving data, we can create metrics to analyze our driving patterns and behavior.
My Comma 3x device
Visit the website for a more comprehensive overview: comma.ai
Set Up Virtual Environment/Install Dependencies (Mac)
Execute these commands in your terminal
Create local virtual env:python3 -m venv .venv
Activate local virtual env:source .venv/bin/activate
import pandas as pd # data processingimport urllib.request # download file from URLimport ssl # bypass SSL certificateimport warnings # ignore non-critical warning outputsimport cv2 # video processingimport matplotlib.pyplot as plt # data visualizationimport matplotlib.image as mpimg # data visualizationimport subprocess # running terminal commands in Python scriptimport seaborn_image as isns # data visualizationfrom requests import get # API requestfrom time import sleep # Prevent triggering the API limitfrom os import environ, listdir, mkdir, makedirs # directory manipulation & file savingimport os.pathfrom dotenv import load_dotenv # load environment variablesfrom tqdm import tqdm # added as a meme, prints unnecessary loading bar in terminal during for loopsfrom moviepy.editor import VideoFileClip, concatenate_videoclips # video editingplt.style.use('ggplot')warnings.filterwarnings('ignore')ssl._create_default_https_context = ssl._create_unverified_contextpd.set_option('display.max_columns', None)load_dotenv()
True
Create Variables for API Requests
The first step to receive the recording of my longest trip (College Station) since installation is making sure I send the correct parameters to the API endpoint. Comma.ai’s API requests require an authentication token and the dongle ID of a user’s Comma device.
After creating the API variables, we can request the API endpoint which returns our driving data in the response output. The first API request will return various metrics from all of my driving trips since installing my Comma 3x. It will provide us with the route name for every trip. For our current task, we have chosen our longest trip by miles, so we will sort the dataset by longest trip to identify the route name. After sorting by descending order, the first row’s value in column fullname is the route name.
API Request #2 - Returns URLs To Download Video Files
Using the route name, we can submit our second API request to an endpoint storing the URLs of our downloadable video files (.ts file type). Before downloading our files, we store the URLs from the API response in a text file, so we can access the URL data locally.
def query_to_extract_urls(BASE_URL: str, route_name: str): df = pd.read_csv(f'{route_data_path}/route_names.csv')# Insert dongle ID into route name route_name_dongle_list = []for idx, row in df.iterrows(): converted_route_name = row['route_name'].replace('INSERT-DONGLE-ID-HERE', f'{DONGLE_ID}') route_name_dongle_list.append(converted_route_name) df['route_name'] = route_name_dongle_list download_recent_trip_vids = df.loc[df['route_name'] == route_name] download_recent_trip_vids = download_recent_trip_vids['route_name'].tolist()for route in tqdm(download_recent_trip_vids):with get(f'{BASE_URL}/v1/route/{route}/files', headers=headers, verify=False, stream=True, timeout=10) as response: content = response.json()['qcameras']withopen(f'{vid_urls_path}'+f'/{route.replace(f"{DONGLE_ID}|", "")}.txt', mode="wb") asfile:for url in content:file.write( url.replace(f"{DONGLE_ID}", "INSERT-DONGLE-ID-HERE").encode('utf-8') +' \n'.encode('utf-8')) urls_list = []withopen(f'{vid_urls_path}'+f'/{route.replace(f"{DONGLE_ID}|", "")}.txt', mode="r") asfile: url_list =file.readlines()for url in url_list: urls_list.append(url)print("Total number of URLs to download:", len(urls_list))print("\n Preview 5 URLs:", *url_list[:5], sep='\n')query_to_extract_urls(BASE_URL=BASE_URL, route_name=f'{DONGLE_ID}|2024-04-07--06-08-29')
Total number of URLs to download: 147
Preview 5 URLs:
https://commadata2.blob.core.windows.net/qlog/INSERT-DONGLE-ID-HERE/2024-04-07--06-08-29/0/qcamera.ts?se=2024-07-26T23%3A26%3A31Z&sp=r&sv=2024-05-04&sr=b&rscd=attachment%3B%20filename%3DINSERT-DONGLE-ID-HERE_2024-04-07--06-08-29--0--qcamera.ts&sig=IeU/1rDLYDyNdO8IfWGuY7lkyqklbWEzXhk4oTXMpNA%3D
https://commadata2.blob.core.windows.net/qlog/INSERT-DONGLE-ID-HERE/2024-04-07--06-08-29/1/qcamera.ts?se=2024-07-26T23%3A26%3A31Z&sp=r&sv=2024-05-04&sr=b&rscd=attachment%3B%20filename%3DINSERT-DONGLE-ID-HERE_2024-04-07--06-08-29--1--qcamera.ts&sig=Utd4haRw/MTRCj9IQ5FuGlG%2BJEw9GteLC1C4hvc6QXw%3D
https://commadata2.blob.core.windows.net/qlog/INSERT-DONGLE-ID-HERE/2024-04-07--06-08-29/2/qcamera.ts?se=2024-07-26T23%3A26%3A31Z&sp=r&sv=2024-05-04&sr=b&rscd=attachment%3B%20filename%3DINSERT-DONGLE-ID-HERE_2024-04-07--06-08-29--2--qcamera.ts&sig=84r3II6Jzj2o2XoZarOZWtdAnBASVU3/0RG39MGIvFg%3D
https://commadata2.blob.core.windows.net/qlog/INSERT-DONGLE-ID-HERE/2024-04-07--06-08-29/3/qcamera.ts?se=2024-07-26T23%3A26%3A31Z&sp=r&sv=2024-05-04&sr=b&rscd=attachment%3B%20filename%3DINSERT-DONGLE-ID-HERE_2024-04-07--06-08-29--3--qcamera.ts&sig=qrJkNwjhOzm4oHXnrxINYvF/yp6tT9SsS%2BFlFUEz934%3D
https://commadata2.blob.core.windows.net/qlog/INSERT-DONGLE-ID-HERE/2024-04-07--06-08-29/4/qcamera.ts?se=2024-07-26T23%3A26%3A31Z&sp=r&sv=2024-05-04&sr=b&rscd=attachment%3B%20filename%3DINSERT-DONGLE-ID-HERE_2024-04-07--06-08-29--4--qcamera.ts&sig=qhgD2bNQInMmdex8Y82SnbhVq5qGgJX9qMttW0cIZbU%3D
Downloading Our Driving Video .ts Files
With our URLs stored locally in a text file, we can iterate over and request each URL to download and save our video files locally. Note: You cannot run this function since I did not provide my API token or dongle id
Video URLs file: data/vid-urls/2024-04-07--06-08-29.txt
Beginning video downloads...
Video files successfully downloaded!
Total files downloaded: 147
Converting File Type to MP4
After looping over the URLs to download our driving videos, we convert our video file type from .ts to .mp4 since it’s one of the most common file types for videos. We store the converted videos in a separate directory, so that we can loop over the 147 files without the original files making trouble.
To facilitate the distribution of video data, Comma API splits our video data into short clips to reduce the memory size. Our objective is to capture images from our entire trip; therefore, we need to concatenate the 147 video files. Ideally, we’d prefer to create one MP4 from the concatenation. Due to storage size, we split the final trip into 4 parts. If we don’t split the video data in this manner, the file size would be too large and we wouldn’t be able to push the video to GitHub.