Autonomous greenhouse robot · ROS 2

Your greenhouse, watched by a robot that drives itself, and a live digital twin.

Lupin explores and patrols a greenhouse with Nav2, reads climate data off AprilTags, finds and grades flowers with YOLO, and streams it all into a digital twin you can drive by voice. ROS 2, simulation and real hardware, fully open-source.

lupin · bring-up
~/ros2_ws$ros2 launch lupin_bringup sim_full.launch.py
Gazebo + SLAM + Nav2 + mission + HMI, one shot
01 · live mission
  • ROS 2 Humble
  • Nav2 · MPPI
  • Mecanum base
  • 23-tool voice
  • Open-source
9
ROS 2 packages
23
voice tools
10 / 6
msgs / services
MPPI
omni controller
Sim + HW
one codebase
MIT
open-source
The problem

A greenhouse has thousands of plants and one grower’s attention.

Climate readings sit scattered on tags down every aisle, plant health is checked by hand, and nobody can be in every row at once. Fixed sensors only see their one spot; a person can’t walk the rows all day.

Let the robot walk the rows.

Rows of tulips under glass at the Tulpen.nl greenhouse, stretching to the horizon
Tulpen.nl · thousands of plants, every aisle
What lupin does

Six capabilities, one robot.

System flow

From an empty map to a live twin.

See it move

Demos.

Drop clips into public/demos/ and they appear here automatically.

02 · autonomous nav (sim)

DEMO VIDEO PLACEHOLDER

drop your clip at public/demos/navigation.mp4

03 · hardware run

DEMO VIDEO PLACEHOLDER

drop your clip at public/demos/hardware.mp4

04 · twin + HMI live

DEMO VIDEO PLACEHOLDER

drop your clip at public/demos/twin.mp4

05 · voice command

DEMO VIDEO PLACEHOLDER

drop your clip at public/demos/voice.mp4

The machine

MIRTE Master V2.

Lupin runs on the course’s MIRTE Master V2, a holonomic mecanum platform with a small manipulator. The same codebase drives Gazebo and the real robot; only the downstream drive topic changes.

Full hardware spec
Lupin robot, front view: the 4-DOF arm raised with a flower in the gripper above its white 3D-printed crate
Front · arm + crate
Lupin robot, rear view: the mecanum drive base and the flower payload riding in the crate
Rear · mecanum base

4-wheel mecanum base

holonomic drive

4-DOF arm + 1-DOF gripper

Hiwonder servos

Orbbec depth + gripper cam

RGB-D + close-up

RPLidar + IMU

SLAM + odometry

Orange Pi onboard

laptop offload

wheel-encoder odometry

sim = hardware

Under the hood

Engineering you can read.

browser-side TF

The HMI walks the /tf tree itself

No tf2_web_republisher: RosProvider subscribes to /tf + /tf_static over CBOR, chains 2D transforms in the browser, and re-renders only when the robot moves >5 mm.

software E-stop

A permanent, heart-beating E-stop

It boots engaged, gates every cmd_vel publish, heartbeats a zero Twist at 20 Hz, and fires CancelGoal at both Nav2 servers, and auto-trips on tab-hide or rosbridge drop.

IDW field

A twin that admits what it can’t see

The get_field service interpolates sensor heatmaps but encodes any cell beyond 1.5 m of a real reading as NaN, so the console paints colour only where data supports it.

frontier BFS

A dependency-free frontier explorer

Pure-Python BFS over the occupancy grid, no numpy, no rclpy, masks unknown-adjacent free cells and scores clusters by size / (1 + distance) to pick the next goal.

The team

Built by Team Lupin.

Six MSc Robotics students at TU Delft (group_14, RO47007 Multidisciplinary Project, 2026 cohort), co-authors, maintainers, and owners of the entire stack, from the mecanum base to the mission console.

Team Lupin at the Tulpen.nl growing facility, with a grower holding a bunch of yellow tulips
Field study · Tulpen.nl growing facility visit

Walk the rows without walking the rows.

Bring Lupin up in simulation with one command, then point it at the real robot. Open-source, ROS 2, sim and hardware.

lupin · bring-up
~/ros2_ws$ros2 launch lupin_bringup sim_full.launch.py
Gazebo + SLAM + Nav2 + mission + HMI, one shot