building a mars rover on two hours of sleep... and winning??
i've been quietly on the FHNW Rover Team for the past months while building many projects in public and working as a cyber defense engineer. yesterday my team and I won first place at the FHNW Rover Träff — every task, overall. the warm-up comp before this year's european rover challenge finals in poland.
i'm writing this on roughly two hours of sleep.
last night i was debugging stuff on our rover at 3am because we found a wiring issue on one of our cameras right before the comp. this morning i was running drone aerial recon with an ai model i finished fine-tuning at 2am over the drone cage of the competition (with boxes as obstacles and aruco tags for spacial recognition). by 4pm we had won the round.
let me back up.
a secret double life?
except a few people in my life, nobody knew about this. but for the past months, while hacking stuff on the side, finding critical CVEs with an automated LLM framework, and working as a cyber defense engineer at the largest retailer in switzerland - i've also been on the FHNW Rover Team.
yes, that same school i transferred to from ETH. yes, i probably should have mentioned this earlier. but it's exactly the kind of random side quest that has no business existing on the same résumé as "building autonomous offensive security tooling" but here we are. that's kind of the whole brand at this point lmao.
i didn't talk about it publicly because the comp was the comp. you don't tweet about the rover until the rover wins.
meet barbara
every team's rover has a name. ours is Barbara — a fully in-house build, designed and assembled at FHNW. CAD, custom machining, custom PCBs, and it's now our job to keep it alive.
the boards are custom. the chassis is custom. the arm is custom. the drill is custom. the autonomy stack is custom. nearly everything that talks to everything else was wired, soldered, and debugged by people who 12 hours later were running the comp.


people sometimes look at student-built rovers and assume "okay so it's a glorified RC car with a webcam." the closer you get to the actual hardware the less that holds. there are 8 camera streams on this rover — 4 on the manipulator (ARM_BASE, GRIPPER, DRILL_TOP, DRILL_BOTTOM), two front/back fisheyes, and two forward Pi cams (Module 3, IMX708) for the high-FPS forward view. plus a ZED stereo for visual-inertial odometry. all of them encoded in hardware on the Jetsons.
2 Nvidia Jetsons live on the rover (jetson-drive for drivetrain + autonomy, jetson-mani for the manipulator and drill); a third Jetson runs as our build server for ci stuff. the operator desk runs on a separate mini-PC and a Thinkpad, both running Ubuntu — we call it the MOS (Mission Operations Station). 30+ containers across all of it, orchestrated with docker-compose + ansible, on a Ubiquiti LAN with Tailscale layered on top for remote ops.
most of the prep happens in the workshop. a hundred small fixes that nobody at the comp ever sees. here's a clip of us bringing our stuff the night before competition:
under the hood

i'm the devops / tell me and i fix whatever breaks quickly with my agents IT guy on the team. doing cybersec stuff gave me the perfect knowledge to create the docker-compose-and-ansible-on-jetsons model. a single push on our gitlab, builds and automatically deploys on the necessary hardware autonomously without having to ssh into any of them. all commands can be executed by our low-code solution - the dashbaord, which I completely rewrote since last year's version. more details below:

here's the stack for the nerds among u:
- ROS 2 Jazzy on Ubuntu 24.04, Cyclone DDS for transport. Static peers list is pinned (no surprise discovery delays mid-task).
- Localisation (needs work - was not fully in use during comp) fuses a 9-DOF IMU, 4-wheel inverse-kinematics wheel odometry integrated via RK4 over a TCP feed from the motor controllers, ZED stereo for visual-inertial (was not working during comp), Blickfeld Qb2 solid-state 3D LiDAR, an SL-LIDAR 2D unit (also not working during comp), and ArUco multi-marker least-squares pose. The estimator is pluggable — we swap between MINS and OpenVINS at launch time depending on conditions. (we have opinions on which one survives the dustier runs.)
- Navigation (also needs work - was not fully in use at roverträff) is
BehaviorTree.CPP v3driving a Dijkstra cost-map planner over a 2892×2892 numpy grid at 66 px/m. Replans the moment we deviate >0.3 m from the plan. Slow mode at 0.2 m/s near waypoints, 0.5 m/s otherwise. The whole thing is a service (fhnw_path_planning_srv) so any node — or the BT itself — can ask for a fresh plan mid-task. - Drone vision is a YOLO model i finished training at 2am the night before the comp, with two weight sets —
best_sun.ptandbest_rain.pt— picked at runtime based on conditions. ArUco PnP for arena reconstruction. A* recovery path with 1 m clearance. - Manipulator uses Dynamixel P-series + XH-series servos via Protocol 2.0, with MoveIt2-Servo running at 200Hz. Small bus-latency trick we picked up from the wiki: register pointers across the two series are remapped so a single Protocol-2.0 bus write hits both kinds of servos in one shot — saves you a round-trip per joint. Operator input for full 6-DOF arm control comes from a 3Dconnexion SpaceMouse Pro Wireless. The same device CAD designers use to rotate models turns out to be the right tool for telling a robotic arm where to go.
- Video pipeline: GStreamer with NVIDIA NVENC (
nvv4l2h264enc) for hardware H.264 on the Jetsons. Each camera publishes 1080p RTSP @ ~1 Mbps for record, 720p RTP @ 2 Mbps for relay, and MJPEG snapshots vianvjpegenc— all in parallel. IDR interval 20,maxperf-enable=true. Bitrate is hot-tunable per-camera from the operator UI via FastAPI (POST /camera/{cam_id}/bitrate). The Pi cams run onayufan/camera-streamer(libcamera → H.264 WebRTC) — replaced an older MJPEG stack the team's wiki politely described as "viel Datendurchsatz und grosse Latenz". - Operator video flows through MediaMTX over WebRTC (WHEP) with hand-tuned STUN/handshake timeouts (2s/5s) and ICE candidates pre-seeded for both LAN and Tailscale so first-frame skips discovery. Sub-second on a clean network.
- MOS dashboard my baby is a Flask + Vite/React stack with Mantine UI,
roslib+ros3d+three.js+recharts+socket.io. We also run RViz2 in a container with X11 passthrough for the cases where nothing beats the real thing. - Camera trick: a custom IMX219 device-tree overlay that multiplexes 4 cameras through a single I2C bus on one Jetson. That's not a stock NVIDIA setup. Took some kernel-level work by our cracked devs Sandro, Melvin, Claude and Gemini.
- CAN bus: a custom in-house CAN-bus controller board sits at the boundary between the high-level ROS world and the actuator side. Bridges raw CAN frames to ROS topics so the navigation graph never has to talk to a motor controller directly.
- Recording: a custom
recorderservice running its own rosbag UI on a dedicated port. Click a task, get the rosbag, replay it, find the bug. - Observability: a new addition by yours truly with the lovely Prometheus + Grafana + Loki + Promtail across every container, plus a custom
ros_topics_exporterthat turns the ROS graph itself into Prometheus metrics. We can debug a failed task by replaying the metrics window after the run. - n8n workflows orchestrating ROS2 nodes via custom
n8n-nodes-ros2integrations. Some of the autonomy logic is literally a low-code drag-and-drop pipeline with ROS topics as the IO. low-code meets robotics, and it works (thanks Sandro!).
the rover träff

yesterday was the fourth international FHNW Rover Träff (Swiss german for "Rovers Meetup") in Windisch — part of the FHNW Robotics Day that also hosts the World Robot Olympiade 2026 (WRO). it's a friendly comp organized by current and former FHNW Rover Team members, where student teams from across europe bring their fully in-house rovers and compete in various tasks on a fake martian terrain on campus. it's not an ERC qualifier — but it is the closest thing we have to a warm-up before the real ERC season. This all happens in a fictional research station scenario in the year 2051.
(yes... we have a real marscape outside the engineering building lol.)
the teams that showed up:
- FHNW Rover Team (us)
- EPFL Xplore — EPFL Lausanne
- Star Dresden — TU Dresden
- FRoST — FH Frankfurt
- ERIG — TU Braunschweig
- ProjectRED — Modena & Reggio Emilia
- WARR — TU München
(ETH Zürich's CRATER team had to withdraw - i think their rover wasn't ready in time. respect. the deadline pressure on these builds is real, and they'd be the first to tell you they'll be back.)


every team brings a different design philosophy. some go big and rugged. some go light and fast. some go for redundancy with multiple arms. you learn more about your own design choices in 30 minutes of watching another team's rover than in three months of reading papers.
the tasks

four mission tasks plus a drone task. each one is its own little hellscape:
1. navigation — autonomous waypoint following on uneven terrain. simple to describe, brutal to actually execute when your IMU is drifting and your wheels are slipping on simulated regolith.
2. sample collection — drill into the ground, extract a sample, deliver it to a target. this one ate the most of our nights leading up to the comp because the drill control loop has zero margin for error.


3. reactor maintenance — turn the right knobs in the right order without the rover (or the simulated reactor) blowing up. the most "video game"-feeling task. somehow also the one that punishes the most when your manipulator is even 5° off.

4. team task — two teams' rovers cooperate to rebuild a damaged water pipeline. yes, two opposing teams' rovers, working together. it sounds collaborative until you remember that 30 minutes earlier you were both trying to score on the same field.


5. drone task — aerial recon over a debris field. spot the markers, build a path, hand it off to the rover. our drone runs a YOLO model i trained at 2am the night before — boxes as obstacles, aruco tags for spatial reference, with two weight sets (best_sun.pt, best_rain.pt) for different lighting conditions.



it worked. judges liked the architecture. that mattered.
EPFL Xplore had their own drone setup running in parallel — different stack, same problem space:
the operator station
every task is run from a small operator's tent we call the MOS (Mission Operations Station) — laptops, monitors, two-way radios, video links to the rover and drone over WebRTC, and a SpaceMouse for 6-DOF arm control. you cannot see the rover directly. you operate blind, off the cameras, with whatever latency the network gives you that day.


the operator station is where the comp is actually won or lost. you can have the best mechanical build on the field; if the operator is fighting their UI, the rover doesn't move where it needs to move.
before each task the judges walk you through the scoring rubric and any rules quirks. it sets the constraints you'll spend the next 20 minutes optimising against:


every team's operator station looked different. some were lean two-laptop setups, some were full mission-control walls. our competitors locked in just as hard:

we won
we won across all challenges :D
first place at every single task. first place overall. dress rehearsal — done.

then they handed us the trophy:

oh, and yes — that's a literal 6 kg block of Swiss cheese we won. the trophy is the rare metal "first place" pokal (fully sponsored ofc), plus a wheel of cheese roughly the size of a small dog. this is what happens when a swiss university hosts a robotics competition.
(we will be eating the trophy. for science.)
the public moment
one of my favorite shots from the day:
a small kid leaning over the railing to take a picture of Barbara mid-task. he could not stop staring. that's the moment the entire weekend was for. some 9-year-old went home telling his parents he wants to build mars rovers. and maybe by the time he's 22 the FHNW Rover Team will be his.
these comps aren't just an engineering exercise. they're a recruiting pipeline for the next generation of swiss engineers. you don't get to that pipeline without showing up.

what comes next

the European Rover Challenge is the real one — the international comp where the world's top student rover teams show up at full strength. it's the bar we're working toward. ERC has its own selection process and that's still ahead of us — yesterday wasn't a path into ERC, but it was the cleanest signal yet that we're in shape for the season. in the last few years FHNW competed at that level and already placed first against ~70 registered teams worldwide. that gave us the bar for this year.
now we have to clear it again with a new generation of the build, against teams that will all show up with their A-game.
if you're a robotics nerd, we might leak some beta with a detailed technical writeup - stuff like control system, autonomy stack, sample drill and the brand new devops setup i built for the team (we run 30+ containers on 3 jetsons w a ubiquiti network as described above).
ok but why??

multitasking is bad i thought?
security research, pwnkit, an open-source SOAR, a record label, audio plugins, a swiss departure board, and now a mars rover??
honest answer: the same skill powers all of it: understanding and actually shipping a system e2e. find the challenging parts, then ship something that survives contact with reality.
a SOC alert pipeline, a fully autonomous vulnerability research engine and a rover autonomy stack have more in common than people think. They're all real-time. they have to handle weird unexpected input (from sensors / alerts / fuzzing). All of them punish you the moment you assume happy-path. They also reward people who can hold the entire stack in their head and intervene at the right level.
(i wrote a whole post about this. the generalist who can move across domains is the one who eats now that AI has compressed the depth.)
and tbh? after months of staring at npm packages and AST diffs, getting to drive a robot across fake martian terrain is the cleanest possible context switch. nothing resets your brain like watching a machine you wrote software for successfully pick up a rock or twisting buttons.
thanks
to the rover team and every single one of you who pulled all-nighters with me, debugged ROS topics at 2am, duct-taped (no yeah the drill was actually using duck tape at some point during the competition), fed each other when none of us had time to eat. this round is yours.
to FHNW — for actually making space for this. you can't build a competitive mars rover at a university that treats students like classroom inhabitants. you can build one at a university that hands them keys to a workshop, sets up a marscape outside the building, and gives them the autonomy to fail and try again.
to the families and friends who showed up today even though most of you have no idea what a rover autonomy stack is — the trophy is also yours.
now i'm going to sleep for fourteen hours and then get back to building.
if you're a sponsor, a recruiter, an engineer who wants to help, or just someone who likes space robots — FHNW Rover Team. doruk@doruk.ch.