A free-running Manta runs at AcquisitionFrameRateAbs, not at its limit:
rietschen's RGB camera came set to 0.955 fps and delivered 5 frames in 5.2 s.
The gige recipe now writes a short fixed exposure and then the rate, clamped
to the camera's maximum (4.7 fps at 60 MB/s), before auto-exposure goes back
on. The export summary shows the rate set, not the limit, which had read
4.71 fps for a camera running at 0.96.
test hardware env asked for a DHT11 reading at once, but the firmware reads
it every 10 s, the first time 2 s after it starts. install-tower --verify
failed on rietschen 1.4 s into its run, 36 s after the same test had passed.
It now waits one read period for the first reading. Tests 542/542 (mock).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Rietschen has three Manta G-1236 on one GbE port, whose firmware predates the
names the program uses. A feature missing by its SFNC name is now looked up by
the older one (ExposureTimeAbs, AcquisitionFrameRateAbs, ExposureAutoTarget,
ExposureAutoAdjustTol), so test camera, the telemetry and the keep rule's
reads work. export_camera_profile.py picks a gige recipe for such a camera:
frame trigger off, BayerRG8 or Mono8, 60 MB/s, auto-exposure target 50 %.
At the cameras' old target of 25 every waypoint ran into frame_timeout_ms.
The camera probe now lists every camera. With several, the hardware.ini kit
writes CHOOSE_ONE, install-tower asks which is the colour one, and the profile
export is given that id - the first one the SDK lists was the NIR camera.
install-tower names the unit that holds the motor port instead of assuming
start_gimbal.service.
Tested on rietschen's NIR camera with the motor mocked, beside the running old
program: test camera PASS, a snapshot as a 3008x4112 grey JXL, a scan keeping
a picture every 5 s. Tests 542/542 (mock build). The colour camera is not yet
tested; the old program has it open.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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>
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>
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>
- 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>
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>