Custom Camera Publisher
Cyclops ships with a usb-camera service that auto-detects UVC cameras and publishes frames into the navigation stack. If your camera isn't UVC — for example a MIPI/CSI sensor or an IP camera — you replace that service with your own publisher.
How Cyclops consumes camera data
Internally, Cyclops uses Eclipse eCAL 5 as its pub/sub bus. MapMatcher subscribes to a single eCAL topic and decodes each message as a Cap'n Proto vkc::Image:
S1/cama
capnp:Image
vkc::Image (image.capnp)
JPEG, grayscale
Anything that publishes onto S1/cama with the right schema is a valid camera source. The bundled usb-camera service is one such publisher; your custom publisher is another.
When you need a custom publisher
UVC USB camera
Bundled usb-camera.service — no integration work
MIPI / CSI sensor
Custom publisher
GigE / IP camera
Custom publisher
Vendor SDK (Allied Vision, FLIR, etc.)
Custom publisher
Any non-UVC source you already have running
Custom publisher
Integration kit
We ship a standalone repo with everything needed to write a publisher without pulling in the SDK:
Inside:
cyclops_camera_ecal.py— Python helper. Build aCyclopsCameraPublisher, callpublish_frame(numpy_array, calibration).cyclops_camera_ecal.{hpp,cpp}— C++ helper with the same contract.example_usb_camera.{py,cpp}— runnable end-to-end examples (OpenCV → helper → eCAL).example_image_subscriber.py— verification subscriber that decodesS1/camaand prints calibration + timing.capnp/— the Cap'n Proto schemas (image.capnpand dependencies), so you can build standalone.camera_params.example.yaml— calibration template that mirrors the on-device YAML shape.
Read the repo README for the full wire contract, field-by-field requirements, and the steps for replacing the bundled service.
Minimum your publisher must do
Capture frames from your camera however you like.
Encode each frame as grayscale JPEG.
Stamp
header.stampMonotonicwith the capture time in the Cyclops host clock domain (useheader.clockOffsetif your camera reports timestamps in another clock).Fill
intrinsic.kb4with calibrated KB4 intrinsics for your lens (fx, fy, cx, cy, k1..k4).Set
extrinsic.bodyFrameto the nadir-mount default(w=0.00202, x=0.70568, y=0.70853, z=0.00170)with zero translation.Publish on eCAL topic
S1/camawith typecapnp:Image.
The helpers in the integration repo handle steps 2–6 for you. You bring camera bring-up (step 1)
Verifying
Run the verification subscriber from any host on the same eCAL network:
A correctly-wired publisher prints encoding=jpeg, monotonically increasing seq, your expected width x height, intrinsics matching your calibration YAML, and body_frame matching the nadir-mount default.
Calibration
External integrators provide camera calibration (intrinsics + the nadir-default extrinsic) and publish it on each frame. Vehicle calibration (b_T_vb) is unrelated — it's handled by the SDK and never flows through your publisher. See Camera Calibration for the calibration procedure.
Last updated
