Commit Graph

28 Commits

Author SHA1 Message Date
Peter Bochmann a326a758c4
Make the thermal camera's frame rate hold on the wire
Setting Framerate_Hz while grabbing only thinned out what the SDK handed over;
the camera went on sending 10 fps (and 50 from power-up). Set while the grab
is stopped, once the stream has run, it holds. So the grab is restarted with
the rate set when the first frame is in, and the packet rate of the camera's
port is counted: if it still carries more than 1.5x the rate's frames, the
restart is repeated (up to three times). On tower 111: 5.3 fps, 2 224 packets
a second instead of 22 234, on the second attempt; system load 18 % down from
about 29 %.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 20:21:49 +02:00
Peter Bochmann 0076e623d0
Set the thermal camera's frame rate once it is grabbing
Set before the first startgrab after connecting, Framerate_Hz answers ok and
changes nothing: the camera went on sending its power-up 50 fps, 31 MB/s and
22 000 packets a second on tower 111, which kept all four cores clocked up for
pictures taken one every 5 s. Set after startgrab it holds (5 Hz: 2 100
packets a second).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 20:10:08 +02:00
Peter Bochmann fc507f7407
Give the thermal picture the time its own frame arrived
Both frames of a waypoint used to take the colour frame's time, which made
the thermal one look taken at a moment it was not: it is the newest frame the
camera had, up to max_frame_age_ms old. Each file and CamEvent now has the
time its own frame reached the host; the two of one waypoint share hdg/pit and
are at most that age apart. The docs say to pair them by that.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 19:42:32 +02:00
Peter Bochmann ff89643a4f
Run the thermal camera's NUC while the gimbal moves
The camera recalibrated against its shutter every 30 s and sent no frame for
about 0.7 s meanwhile: a picture falling into that had no thermal image (0.8 %
on tower 111, the 30 s rhythm shown by the new gap logging). The program now
switches the camera's timer off and runs the NUC itself (NUC_Perform, which
returns when it is done) when a move starts and nuc_interval_s (30) has passed,
or after twice that with no move. The scheduler tells the cameras of every move
(ICameraSource::moving), and a picture waits up to 1 s for a camera between
frames (frameReady) rather than go without it. The camera's own timer goes
back on exit; nuc_interval_s = 0 leaves it alone.

Measured on tower 111 before writing it: NUC_Interval = 0 gave 70 s without a
gap; NUC_Perform ran three NUCs of 657-677 ms; NUC_INPROGRESS never changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 19:02:20 +02:00
Peter Bochmann 1c2f0a0506
Log why a picture got no thermal frame
Every miss now says how old the newest frame was and whether a NUC was
running; every pause over 500 ms in the frame stream is logged with the
camera's own clock, the polls and getdata answers in it, and NUC_INPROGRESS,
which is watched on every poll; a summary of the stream goes out every ten
minutes, and the NUC configuration at connect. Adds the SDK's NUC parameters
(410-415), for running the NUC on purpose later.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 17:59:49 +02:00
Peter Bochmann 474e3cac8a
Fix what the thermal camera's first run on tower 111 showed
- The thermal frame was numbered camera 0 - label RGB, and the colour file of
  the same time overwritten - because Vimba counts no camera before open().
  The composite now takes each source's configured camera count, and two
  enabled cameras may no longer share a label.
- The SDK switches LC_NUMERIC to de_DE when loaded, which made "hotx":0,4336.
  Its calls now run under a guard that restores the locale, and the JSON's
  numbers no longer go through printf.
- The camera's frame counter is always 0: new frames are told by their time,
  so the stream no longer stops after the first one.
- The LUT is empty for the first frame: it is asked again on later ones.
- The SDK is libirbgrab_x86_64-linux.so in the ld cache.
- The null channel traces the CamEvent payload it would have sent.

Tested on tower 111 with the TarisIR mini, the motors mocked: cap_net_raw is
enough, RGB/TIR pairs with one timestamp, the TIR file decodes to the counts
its CamEvent describes, profile switches 0-1-0. 536/536 in the 22.04 container.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 21:01:33 +02:00
Peter Bochmann 3d90af8490
Take a thermal picture beside the colour one at every waypoint
A TarisIR mini (driver = taris) is a second camera source behind a
CompositeCameraSource: the colour camera is asked first, then the thermal one
for its newest frame, and both frames carry the colour frame's timestamp.
Counts are saved 16-bit lossless under TIR/, and the CamEvent gains cal,
missed, tmax, tmed, hotx and hoty (docs/mqtt-api.md). The SDK is declared in
IrbgrabApi.h and loaded with dlopen, so no SDK file is in the repository; a
missing or unreachable camera stays offline (Health cams_offline) while the
scan goes on. scripts/fgc-setcap gives the binary cap_net_raw after a build.

Built and tested in an Ubuntu 22.04 container (mock, MQTT, Vimba+MQTT,
534/534), plus a mock run with RGB/TIR pairs. Not yet run against the camera.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 20:37:25 +02:00
pgdalmeida 6fa43f1e08
Slow down, then pause, the scan when the tower computer runs hot or cannot keep up 2026-10-08 17:21:58 +02:00
pgdalmeida 70a30132bf
Merge counting the picture interval from the last picture and waiting for a slow camera's next frame 2026-10-05 13:02:13 +02:00
pgdalmeida cfd8ba9978
Save raw 12-bit camera frames as 12-bit colour images, keep a waypoint's picture once the image has settled, and hold the scan when saving falls behind 2026-10-05 10:14:53 +02:00
pgdalmeida 62131d8083
Wait for a slow camera's next frame instead of restarting the stream, and read integer camera features for the exposure check 2026-10-04 16:12:44 +02:00
pgdalmeida fb0f5117df
Count the picture interval from the last picture, and let a settle wait of 0 wait for the exposure to settle 2026-10-02 18:28:40 +02:00
pgdalmeida 4488a2181d
Set in config.ini whether the tower homes and which mode it starts in, instead of the --init and --start flags 2026-09-30 16:42:48 +02:00
pgdalmeida 895c2f22fd
Add a command to keep taking pictures where the gimbal points, drop unused camera commands, and fit the help on one page 2026-09-29 15:48:07 +02:00
pgdalmeida d8d2fee8af
Test the camera with forced dark and bright settings, and recover a camera that stops sending frames 2026-09-24 17:35:37 +02:00
pgdalmeida 5a0515ab13
Test that the camera delivers frames and follows its settings to black and white 2026-09-24 15:47:58 +02:00
pgdalmeida 1a572cb074
Changed heading logic; added snapshot feature 2026-09-11 17:42:01 +02:00
pgdalmeida 8eda0b4a36
Added IMU pitch to CamEvent; Changed IMU reading to before jxl encoding to avoid lag 2026-09-09 13:04:25 +02:00
pgdalmeida a5ad814260
Camera settings now come from VimbaX profile XMLs; explicit per-camera config 2026-09-04 14:12:05 +02:00
pgdalmeida f1342965de
Camera is now configured by per-mode files; quality gate removed 2026-08-26 15:52:47 +02:00
pgdalmeida 02d3f573cf
Image rotation is now configurable via Camera.rotation_deg 2026-08-26 14:14:49 +02:00
pgdalmeida 376e79536c
camera logic improved 2026-08-07 15:04:47 +02:00
pgdalmeida c41cb6fc6a
Added camera control 2026-07-13 19:15:38 +02:00
pgdalmeida d4d1993a25
added extra encoder tracking information 2026-06-29 23:35:45 +02:00
pgdalmeida 09b032b998
added terminal user interface (TUI) 2026-06-23 13:21:34 +02:00
pgdalmeida 14707c62ae
Migrate host to the current firmware serial protocol (counts/MOVE/ST) 2026-06-22 23:44:13 +02:00
pgdalmeida 90f689c829
Add per-category verbatim wire tracing 2026-06-22 22:30:26 +02:00
pgdalmeida 11a2384c53
Modularize into interfaces with real + mock implementations 2026-06-22 12:51:57 +02:00