Architecture of the Acquisition Controller
Class diagram

Modules
Cameras
To support a variety of camera protocols, a generic HeliolyticsCamera serves as the base class for all types of camera
possibly supported by the controller. Currently, the cameras on the rig utilize two protocols, the proprietary Lumenera
protocol and the standard GenICam protocol. SDKs are distributed for both protocols so a wrapper is created to implement
the base interface, LumeneraCamera and SpinnakerCamera respectively. Additionally, a CameraFinder class is
responsible for enumerating and constructing the cameras according to the configuration listed in the config files.
Again, each protocol may have a different enumeration process so protocol specific code must be implemented in the
CameraFinder. Once constructed, the camera pointer is handed over to the CameraManager who will own the
resource for the rest of its lifetime.
Exposure Control
As was the case in the legacy AUI implementation, UFs has the ability to dictate exposure parameters, namely shutter speed and gain,of a camera based on the auto-exposure settings provided by another camera. The most likely use case for this feature is the use of the HFR camera to dictate the exposure parameters of the highres LUM camera.
To achieve this function, cameras can be registered as exposure "master" or exposure "slaves". A callback will be registered with the master which is to be called when the master receives a new image. This callback is responsible for recomputing new exposure parameters and reconfigure the slave cameras.
SMC
Communication with the SMC is handled by a helper class conveniently named SmcMediator. It provides the functions to
connect, receive, and decode the messages from the SMC. Status updates are sent asynchronously from the SMC and thus
all the reception and decoding logic of the mediator is executed in a thread detached from the main thread. To be
notified of new statuses, the AcquisitionController registers a callback function with the mediator. That function is
invoked from the SMC reception thread so logic in the callback should be kept to a minimum.
In the current implementation, the status is added to a queue along with a timestamp. The processing of that queue happens in the main thread.
Synchronization
Without a doubt, the single hardest challenge in the acquisition controller is to synchronise the images received. In order to be usable, the images from each camera must be matched to a telemetry update. Only then do we have a meaningful frame. Unfortunately there is no easy and robust solution to this yet. The current strategy utilizes a simple first in first out queue mechanism.
The synchronization logic lives in a separate class, the SynchronizationManager which registers a callback with each
camera node. When an image is stored, the callback is called and an entry is added to the corresponding camera's queue.
Same thing when a telemetry sample is received.
Synchronisation is achieved by assuming the first element of each queue belongs together to form a frame. This is a very vulnerable assumption which relies on the camera nodes to never miss an image, or notify the manager that an image was missed should some error happen.