NiFT Autonomous Shuttle
Undergraduate Research Winter/Fall 2026 Entrepreneurship Grade: #
Info Detail
------- -------
TIME Jan 2026 – Present
LAB/ORG Perot Jain TechLab, Mcity @ U-M; NiFT
ROLE System Integration Engineer
STACK Python, C++, ROS 2, CAN bus, Gazebo, Git, Linux
Mission
This project aims to develop an autonomous depot shuttle platform for Mcity in collaboration with NiFT. Our goal is to deliver a proof-of-concept transforming the NiFT Shuttle QB into an L4 autonomous vehicle by leveraging infrastructure-based sensing and routing.
Interactive URDF: Click and drag to inspect the shuttle's sensor payload and chassis.
As part of a six-person student team, I architected the end-to-end ROS 2 Humble software stack, bridging high-level autonomy with low-level hardware execution. My core achievements include developing a custom Active Disturbance Rejection Control (ADRC) system alongside an adaptive pure pursuit planner, engineering the SocketCAN communication bridge for by-wire control, and integrating RTK GNSS localization with a fail-safe hardware state machine. To validate our navigation algorithms prior to physical deployment, I also built a high-fidelity Gazebo simulation environment of the Mcity testing grounds, complete with custom URDF models and RViz 2 diagnostic tools.
Implementation
I architected the ROS 2 workspace to achieve the Sense-Think-Act pipeline for the shuttle. For testing, simulation is also developed. The system can be split into 4 core layers:
- LiDAR-Based Obstacle Detection: Processed raw point cloud data to extract obstacle coordinates and implemented spatial transformations (
TF2) to map object detections from the sensor frame to the vehicle's local coordinate system. - GNSS-Based State Estimation: Developed an integration for Mcity Octane via Socket.IO to stream global positioning data. Implemented a dual-beacon configuration to accurately compute the shuttle's absolute heading and real-time coordinates.
- CAN Bus Integration: Utilized
ros2_socketcanto interface with the vehicle's control bus. I performed frame decoding using proprietary DBC files to map raw bus signals, including throttle, brake, gear, and steering. - By-Wire Controller: Developed a controller node to bridge high-level ROS 2
Twistcommands with low-level CAN frames. This included implementing a Finite State Machine (FSM) and ADRC controller to translate target velocities and steering angles into precise actuator setpoints.
- Environment Mirroring: Engineered a digital twin of the NiFT shuttle and Mcity depot within Gazebo and Rviz2, ensuring accurate physical modeling and sensor data replication.
- Parity Testing: Structured the simulation nodes to be "plug-and-play" with the physical hardware nodes. This meant the exact same Planner and CAN nodes were used in both sim and reality, significantly reducing deployment bugs.
RViz2 Telemetry: Adaptive Pure Pursuit tracking the generated Bezier trajectory.
Challenges
CAN Bus & Hardware
Coming into the project with no prior CAN experience, the learning curve for low-level vehicle communication was steep.
- CAN Frame: I moved beyond high-level code to understand the bit-level details of the DBC file. I had to learn how to manually manipulate bytes to input meaningful velocity and steering data into CAN frames.
- Linux Networking: A major hurdle was configuring the Linux Kernel to recognize our Kvaser interface. I spent significant time troubleshooting the bridge between
can-utilsand the hardware, eventually successfully masking our laptop as a native node on the vehicle’s bus.
Software & API
The L4 aspect of NiFT shuttle relies on external data, which introduced unique software integration challenges.
- Real-time External Comms: I had to implement a Socket.io client within our ROS 2 stack to communicate with the Mcity Octane API. Ensuring that infrastructure-based routing data reached our planner with minimal latency was critical for safe operation.
- ROS 2 Ecosystem: Beyond just writing nodes, I had to master managing complex Parameter files, launch configurations, and package dependencies to ensure the system was modular and reproducible for the rest of the team.