About me


I’m Chien-Chih Ho (Ernie Ho), the master student at Carnegie Mellon University, School of Computer Science, Robotics Institute. Previously, I was a visiting researcher at Massachusetts Institute of Technology (MIT) Electrical Engineering and Computer Science (EECS).

My interests include Artificial Intelligence, Machine Learning, Deep Learning, Reinforcement Learning, Computer Vision, and Autonomous Vehicles!

I loved building, hacking and inventing stuff!

Here I built the autonomous racecar from scratch.


My classmates and I made the mini racecar run through the MIT tunnel autonomously.

You can see the details in the following links:

Racecar Part 1: How to build the autonomous car?

Racecar Part 2: Set up the environment

Racecar Part 3: Reflexive Control

Racecar Part 4: Computer Vision

Racecar Part 5: Mapping and Localization

Racecar Part 6: Motion Planning

Racecar Part 7: Challenge Design Document

Later on, I joined MIT Media Lab Changing Places Group and devoted myself to the next generation of Autonomous Vehicle- PEV.

Besides from building autonomous vehicles, I also did the social mining in Andorra and action recognition using machine learning and deep learning tools.

Social Mining: Andorra Social Mining Approach

Social Mining: Andorra Social Mapping Website

Empathetic Action Recognition

The following are the details of the links above, if you are interested in the topic, you can click into each post to see more details.

Racecar Part 6: Motion Planning

Table of Contents

Path planning with RRTs





The goal for this lab was to create a path planning algorithm that could navigate the robot down a corridor whilst avoiding obstacles. To achieve this, we implemented a Rapidly-exploring Random Tree (RRT) algorithm and made modifications to previous path following algorithm. Final results were that we were able to drive down a hallway in the Gazebo simulator using a pre-recorded map-file.

Continue reading “Racecar Part 6: Motion Planning”

Racecar Part 5: Mapping and Localization

There were three primary goals for this part. These were:

  • Mapping: Collect Odometry, LaserScan, and Transform data with the racecar, in order to create a map on the VM. Do this using existing tools within the ros infrastructure
  • Localization: Using the pre-recorded map information, create a particle filter to find the pose of the racecar using realtime Odometry and LaserScan data.
  • Control: Given a preset path, design a controller which causes the robot to follow the path.

Table of Contents


A handful of ros bag files were recorded of the robot driving through some MIT corridors. A launch file was then used to play back these bags alongside a node from one of ROS’ mapping packages. Two tools were tried – hector_slam, and gmapping.Despite attempts at tuning parameters, we encountered significant problems with the performance

Despite attempts at tuning parameters, we encountered significant problems with the performance of gmapping, which would update its map too infrequently for it to successfully match scans. We worked around this by simulating everything at 1/20th real-time, using a-r 0.05 argument to the rosbag node. This gave gmapping plenty of time to catch up.

hector_slam was able to produce a map of similar quality to gmapping, but could do so without the aid of a slower bag.

Both mapping strategies had a flaw where they would create walls behind the car. This was discovered to be because the laser scanner was detecting parts of the car. This was fixed by narrowing the range of angles that the laser would scan.


To achieve localization we implemented a particle filter to combine odometry and laser scan information. Particles were tracked as 2-dimensional poses consisting of x, y, and theta. The motion update step occurred each time odometry information was received, producing one particle from each existing particle based on the motion dynamics specified by the odometry and perturbed by a covariance we estimated. The sensor update occurred each time laser scan information was received, using Bresenham ray-tracing to estimate the likelihood of each particle given the map produced by the SLAM algorithms in part 1, resampling the particles based on these weights to improve the estimates.

Continue reading “Racecar Part 5: Mapping and Localization”

Racecar Part 4: Computer Vision

In this part, the goal was to use the cameras on the racecar to navigate around a bright orange cone. This entailed writing computer vision code to identify the cone, and a controller to weave around the cones smoothly.

Part 4A Autonomous Racecar Vision With Pose

Part 4A Autonomous Racecar Vision Without Pose

Part 4A Autonomous Racecar Visual Servoing

Table of Contents

Software Architecture


Computer Vision

The ZED camera publishes an Image topic with images from the front of the robot like this one:



There are two different things that could be looked for when trying to locate the cone in this image – shape, and color. Our implementation chose to discard shape, and classify cones exclusively by color. In order to do this, the color of the cone must be measured.

A video of a static cone was recorded, with the lighting conditions varying. This aimed to capture all the possible colors that the cone could appear as. As the cone did not move within the frame, it was possible to hand-draw a mask over a single frame, to label where the cone is. Samples can then be taken from all the pixels under the mask, for every frame, yielding a large dataset of shades of cone-orange.


Using this data, there are a number of common options for building a classifier:

  • choose upper and lower bounds for R, G, and B
  • choose upper and lower bounds for H, S, and L
  • find a small set of planar classifiers – a set of planes which contain the region of color-space holding orange colors. This generalizes the above two options
  • Attempt to use machine learning to come up with non-linear classifiers

A little more thought revealed a much simpler option – building a lookup table from color to orangeness. The following plots show the collected color data as voxels, where a voxel is filled if at least one of the samples of the cone falls inside it.


Some thought must be put into choosing voxel sizes: too small, and the size of the lookup table might cause cache invalidation performance issues, and unless a very large amount of data is recorded, the tables will be sparse; too large, and the classifier will group non-orange colors with orange. Settling on a total of 83 voxels.

The output of the thresholder is the result of taking every pixel in the raw image, and looking up how many times that region of pixels occurred in the calibration sample. The result is returned as a grayscale image, with white representing the colors seen most in calibration, and black representing colors never seen in calibration.

Blob Detection

Continue reading “Racecar Part 4: Computer Vision”

Racecar Part 3: Reflexive Control

In part 3, the goal was to create a rudimentary pipeline for following a wall while checking for collisions in front. To accomplish this, we divided the task into natural functionality segments both to better organize code structure as well as to add modularity for future functionality to build off of. In addition, we continued to add infrastructure to make writing ROS code with good practices easier.

rviz results from simulated laser scan


Table of Contents


Scan Parser

The lowest level of functionality is the scan parser node, which takes input directly from the scanner and manipulates it into a form more useful for the rest of the nodes to use. First, the laser scan is divided into 3 segments: front, left, and right. The division between the three scans is determined by input from the ROS parameter service. Each of these reduced laser scans is republished to its own topic so other nodes can look only at the portion of the scan they require, and many nodes can look at each trimmed scan without recomputing the trim operation.

The other operation the scan parser completes is to transform the LaserScans into PointCloud2s using the laser_geometry package. The point cloud format enables a node like a wall detector to access the scan information in a potentially more convenient way, for example, if it is going to perform regression or other operations on the points of the scan in cartesian space. A point cloud is published for each of the trimmed down scans as well.

The scan parser is also responsible for ignoring points which are the robot sighting itself. It does this by dropping samples outside of a particular angle band.

Object Detector

The object detector looks at the laser scan from the front of the robot to check for any close objects which could cause a collision. Using the trimmed scan from the scan parser, it counts the points within a distance threshold and publishes a boolean indicating whether there are sufficiently many points within this threshold. The threshold for distance and for the number within that distance are determined by input from the ROS parameter service.

Continue reading “Racecar Part 3: Reflexive Control”