CitrusFarm

CitrusFarm (https://ucr-robotics.github.io/Citrus-Farm-Dataset/): a Clearpath Jackal driven through citrus orchard rows.

Each sequence ships a “base_*.bag” (LiDAR+IMU+GPS) – most sequences split across several parts, which must all be replayed, in recording order – and a matching “odom_*.bag” (wheel odometry).

base_link is the Microstrain GX5 IMU, at identity; the extrinsics below come from the dataset’s own CAD + Kalibr calibration chain, not from a placeholder. lidar_odometry_from_citrusfarm.yaml carries the same values as its defaults.

Wheel odometry is NOT fused by default, and that is deliberate rather than an oversight: mrpt::obs::CObservationOdometry cannot carry a sensor pose at all, so the ~180 deg yaw between the Jackal chassis frame and the “imu” frame the rest of the pipeline uses is silently discarded, and the increment gets fused pointing the wrong way. Set MOLA_ODOMETRY_TOPIC explicitly if you want it anyway. Revisit once CObservationOdometry rotation exists upstream.

Running it

Online replay with the 3D GUI:

mola-lo-gui-citrusfarm /path/to/base_*.bag [more base_*.bag parts] [/path/to/odom_*.bag] [additional flags]

Offline batch run, writing a trajectory file:

mola-lo-cli-citrusfarm /path/to/base_*.bag [more base_*.bag parts] [/path/to/odom_*.bag] [additional flags]

What this profile sets, and why

These are defaults, not overrides: exporting any of these variables before running the wrapper takes precedence.

MOLA_LIDAR_TOPIC

Default: /velodyne_points

MOLA_IMU_TOPIC

Default: /microstrain/imu/data

LIDAR_POSE_X

Default: 0.0285

T_imu_lidar, derived from CAD + the Kalibr calibration chain. There is no /tf or /tf_static in these bags, so fixed poses are mandatory.

LIDAR_POSE_Y

Default: 0.0091

T_imu_lidar, derived from CAD + the Kalibr calibration chain. There is no /tf or /tf_static in these bags, so fixed poses are mandatory.

LIDAR_POSE_Z

Default: 0.0776

T_imu_lidar, derived from CAD + the Kalibr calibration chain. There is no /tf or /tf_static in these bags, so fixed poses are mandatory.

LIDAR_POSE_YAW

Default: 179.8419

T_imu_lidar, derived from CAD + the Kalibr calibration chain. There is no /tf or /tf_static in these bags, so fixed poses are mandatory.

LIDAR_POSE_PITCH

Default: -0.3290

T_imu_lidar, derived from CAD + the Kalibr calibration chain. There is no /tf or /tf_static in these bags, so fixed poses are mandatory.

LIDAR_POSE_ROLL

Default: 0.1130

T_imu_lidar, derived from CAD + the Kalibr calibration chain. There is no /tf or /tf_static in these bags, so fixed poses are mandatory.

MOLA_USE_FIXED_LIDAR_POSE

Default: true

T_imu_lidar, derived from CAD + the Kalibr calibration chain. There is no /tf or /tf_static in these bags, so fixed poses are mandatory.

IMU_POSE_X

Default: 0}" ; : "${IMU_POSE_Y:=0}" ; : "${IMU_POSE_Z:=0

T_imu_lidar, derived from CAD + the Kalibr calibration chain. There is no /tf or /tf_static in these bags, so fixed poses are mandatory.

IMU_POSE_YAW

Default: 0}" ; : "${IMU_POSE_PITCH:=0}" ; : "${IMU_POSE_ROLL:=0

T_imu_lidar, derived from CAD + the Kalibr calibration chain. There is no /tf or /tf_static in these bags, so fixed poses are mandatory.

MOLA_USE_FIXED_IMU_POSE

Default: true

T_imu_lidar, derived from CAD + the Kalibr calibration chain. There is no /tf or /tf_static in these bags, so fixed poses are mandatory.

MOLA_OBSLAYER_MAX_DISTANCE_FOR_COV

Default: 1.0

Keep the observation layer’s covariance neighborhood at the map class’s own 1.0 m, against the 2.0 m the pipeline now defaults to. This is the one dataset in the curated corpus where the wider neighborhood loses: APE x1.201 over 7 sequences, worse on 5, with two past x2. Dense close-range orchard foliage has no consistent surface to fit, so a wider neighborhood averages the scan-side normal over vegetation rather than structure.

Under the hood

Online launch file

lidar_odometry_from_citrusfarm.yaml

Offline CLI input

--input-rosbag1 <cli_bags>

Profile source

scripts/lib/profiles/citrusfarm.sh