Bretl Lab
2024

As UAVs and emerging air-taxi systems face serious safety risks during landing and takeoff, I participated in a study examining the robustness of fiducial-marker detection under challenging environmental conditions. Through extensive work in ROS-based data synchronization, sensor calibration, and pose-estimation pipelines on a DJI Matrice 300 RTK, I deepened my understanding of aerial robotics
Key Contributions:
- Environmental Perception: Contributed on quantifying environmental effects on UAV perception, assessing how lighting, wind, and precipitation influence fiducial marker detection and pose estimation
- Sensor Synchronization and Embedded System: Synchronized the DJI Matrice and Boson 640 cameras for reliable sensor acquisition, achieving temporal alignment within 1 ms at 60 Hz through telemetry-based timestamp calibration.
- ROS Integration and Data Pipeline: Developed a ROS-based data acquisition and publishing pipeline for real-time sensor communication and pose estimation, enabling consistent evaluation of perception robustness in dynamic outdoor conditions.
With the rapid growth of drone service startups—from delivery systems to emerging air-taxi platforms—ensuring operational safety has become increasingly critical. Yet, much of existing research remains confined to controlled laboratory settings, which fail to reflect the complexity of real-world environments. I participated in a study that quantified the environmental effects on UAV perception, analyzing how factors like lighting, wind, and precipitation influence detection and pose estimation—contributing to safer and more reliable autonomous flight operations.








Motivation
Precise landing is critical for UAV and VTOL systems
where even minor perception errors can cause instability or accidents. Fiducial markers, commonly used in robotics and augmented reality for localization and pose estimation, are particularly valuable for enabling autonomous takeoff and landing of rotorcraft.
Most prior research has been limited to controlled indoor experiments
which fail to capture the complexity of real outdoor environments. Factors such as changing illumination, temperature, wind, and rain can significantly degrade marker detection and pose-estimation performance from flying vehicles.
Aiming to quantify how environmental conditions affect both detection reliability and pose accuracy
bridging the gap between laboratory evaluations and real-world outdoor operations for autonomous aerial systems.
Approach
1. Multi-scale Fiducial Marker Design
As a UAV approaches a landing pad, it must detect markers across multiple distance ranges—from far approach to close touchdown. To ensure reliable detection throughout the descent, we used a nested multi-scale fiducial marker layout, allowing consistent recognition at long, medium, and short ranges.
2. Pose Estimation
Marker detection was performed using the AprilTag library, which identifies the pixel coordinates of each marker’s corners. The pose estimation process then solved a Perspective-n-Point (PnP) problem, relating the known 3D coordinates of the marker corners to their detected 2D image projections to compute the UAV’s position and orientation relative to the landing pad.
As a result, we figured out that low light is the most critical failure. Also, the motion blur from the speed and wind degrades pose estimation.
Method & Contribution
Sensor Synchronization: Achieved <1 ms synchronization between color and thermal cameras to ensure precisely aligned frames for reliable marker detection.
To accurately perceive the fiducial markers, it was essential to synchronize the color and thermal camera inputs. I implemented a synchronization setup between the DJI Matrice 300 RTK’s onboard color camera and an added Boson 640 thermal camera, achieving a timing offset of less than 1 ms. The synchronization was carried out in two stages: each time the main camera captured a frame, it generated an electrical trigger signal, which the thermal camera received to capture its corresponding frame simultaneously. This ensured precise frame alignment across both visual and thermal modalities for reliable marker detection under varying environmental conditions.
Extract Timestamp from Telemetry: Parsed Boson telemetry to recover hardware timestamps and integrate them into ROS, ensuring precise thermal–sensor alignment.
I enabled the telemetry mode of the FLIR Boson 640 to extract embedded metadata directly from each frame. The telemetry data—appended to the last two rows of every 16-bit image—contains information such as sensor status and precise frame completion timestamps. Using a custom parser, I extracted the timestamp from the four 16-bit telemetry words, reconstructing a 64-bit millisecond counter representing the exact moment the camera finished capturing the frame.
On the host computer, each frame arrival was also recorded using the ROS system time. By comparing the Boson’s internal timestamps with the ROS timestamps, I calculated the communication offset between the camera and the onboard computer. This alignment allowed me to achieve precise temporal synchronization between the thermal camera and other onboard sensors, enabling accurate multi-sensor data fusion.
Telemetry Table
| Byte Start | Number of Byte | Name |
| 0 | 2 | Telemetry Revision |
| 2 | 4 | Camera Serial |
| 6 | 4 | Sensor Serial |
| 54 | 2 | Frame Rate |
| 94 | 2 | Camera Temperature |
| 280 | 4 | Time Stamp in msec |
Boson Telemetry Timestamp Parser Code
<!-- wp:code -->
<pre class="wp-block-code"><code>static std::optional<uint64_t> getBosonTimestampMs(const cv::Mat& thermal_img) {
if (thermal_img.empty() || thermal_img.type() != CV_16UC1 || thermal_img.rows < 2) return std::nullopt;
// Telemetry region (vendor/mode-specific): last 2 rows, flattened as uint16_t
const cv::Mat tele = thermal_img.rowRange(thermal_img.rows - 2, thermal_img.rows);
const auto* w = tele.ptr<uint16_t>(0);
const size_t words = tele.total();
// Example indices (verify for your Boson telemetry layout):
if (words <= 143) return std::nullopt;
const uint16_t w0 = w[140], w1 = w[141], w2 = w[142], w3 = w[143];
// Compose 64-bit ms counter from four 16-bit words (adjust if your device uses 32-bit)
const uint64_t ts =
(static_cast<uint64_t>(w0) << 48) |
(static_cast<uint64_t>(w1) << 32) |
(static_cast<uint64_t>(w2) << 16) |
static_cast<uint64_t>(w3);
return ts;
}</code></pre>
<!-- /wp:code -->
Boson Thermal Image ROS Publisher
static void publishThermal(
ros::Publisher& img_pub,
ros::Publisher& info_pub,
const sensor_msgs::CameraInfo& ci_template,
const cv::Mat& thermal_img,
bool raw16_encoding, // true: mono16 (RAW16), false: mono8 (AGC8)
const std::string& frame_id)
{
// Derive stamp from telemetry when available
ros::Time stamp = ros::Time::now();
if (auto ts = getBosonTimestampMs(thermal_img)) {
const uint64_t ms = *ts;
stamp = ros::Time(ms / 1000ULL, (ms % 1000ULL) * 1000000ULL);
}
// Build Image message
sensor_msgs::Image img;
img.header.stamp = stamp;
img.header.frame_id = frame_id;
img.height = thermal_img.rows;
img.width = thermal_img.cols;
img.encoding = raw16_encoding ? "mono16" : "mono8";
img.is_bigendian = false; // Boson outputs little-endian
img.step = static_cast<uint32_t>(thermal_img.step);
img.data.assign(thermal_img.datastart, thermal_img.dataend);
img_pub.publish(img);
// Publish matching CameraInfo
sensor_msgs::CameraInfo ci = ci_template;
ci.header.stamp = stamp;
ci.header.frame_id = frame_id;
info_pub.publish(ci);
}
Using the telemetry data table above, I successfully parsed key parameters such as the serial number, frame rate, camera temperature, and timestamps. Because the Boson was operating in 16-bit thermal mode, I had to reinterpret the raw 8-bit bytes as 16-bit words to decode the data correctly. Monitoring the camera temperature was particularly important, as thermal drift directly affects sensor performance and the accuracy of temperature-based imaging.
Using the extracted telemetry timestamps, I integrated the data into the ROS publishing pipeline. Since ROS time follows the format sec.nsec, I converted the Boson’s millisecond-based timestamp into seconds and nanoseconds by dividing and multiplying by 1000, respectively. This ensured that each thermal frame carried a precise hardware-captured timestamp rather than relying solely on system time. The aligned timestamps were then published through ROS using both Image and CameraInfo topics, enabling accurate multi-sensor synchronization and consistent temporal reference across the system.
What Did I Learn?
1. Troubleshooting through communication
My initial goal was to synchronize the thermal camera’s frame rate with the UAV’s trigger signal. However, despite extensive testing, the thermal camera would not align with the drone’s 60 Hz frame rate and remained stuck around 23 Hz. After exhausting local debugging, I reached out to the camera’s OEM, the equipment provider, and other labs at UIUC that had used the same model. Through these conversations, I learned that the issue required a software-level adjustment—specifically switching the camera’s internal “Trigger Mode” to Master Mode, a setting poorly documented in the manuals. This experience taught me the value of persistence, clear communication, and collaboration when solving hardware-software integration problems.
2. Robotics and Embedded Systems
This project was a turning point in my understanding of robotics. As an undergraduate mechanical engineering student, I had long sought hands-on experience beyond theory. Working with UAVs and integrating sensors through ROS gave me practical exposure to synchronization, real-time data processing, and embedded programming. These experiences not only strengthened my low-level coding skills but also laid the foundation for my later robotics projects, where I continued to build on what I learned about system integration and software-hardware interaction.
