Commit 754cc7d9 authored by Éric Thiébaut's avatar Éric Thiébaut
Browse files

Add remote cameras

This is a preliminary version of the API for remote cameras which
temporarily coexist with shared cameras.
parent 660db61c
......@@ -69,6 +69,8 @@ include_HEADERS = \
tao-options.h \
tao-preprocessing.h \
tao-remote-mirrors.h \
tao-remote-cameras-private.h \
tao-remote-cameras.h \
tao-remote-mirrors-private.h \
tao-remote-objects.h \
tao-remote-objects-private.h \
......@@ -98,6 +100,7 @@ libtao_la_SOURCES = \
errors.c \
locks.c \
logmsg.c \
remote-cameras.c \
remote-mirrors.c \
remote-objects.c \
rwlocked-objects.c \
......
// remote-cameras.c -
//
// Management of remote cameras.
//
//-----------------------------------------------------------------------------
//
// This file if part of TAO real-time software licensed under the MIT license
// (https://git-cral.univ-lyon1.fr/tao/tao-rt).
//
// Copyright (C) 2019-2022, Éric Thiébaut.
#include "tao-remote-cameras-private.h"
#include "tao-config.h"
#include "tao-errors.h"
#include "tao-generic.h"
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#define BUFFERS_OFFSET TAO_ROUND_UP(sizeof(tao_remote_camera), sizeof(tao_shmid))
static inline tao_shmid* get_bufs(
tao_remote_camera* cam)
{
return (tao_shmid*)TAO_COMPUTED_ADDRESS(cam, BUFFERS_OFFSET);
}
tao_remote_camera* tao_remote_camera_create(
const char* owner,
long nbufs,
unsigned flags)
{
// Check arguments.
if (nbufs < 2) {
tao_store_error(__func__, TAO_BAD_SIZE);
return NULL;
}
// Compute stride, offest, and size to store `nbufs` shared memory
// identifiers.
size_t stride = sizeof(tao_shmid);
size_t offset = TAO_ROUND_UP(sizeof(tao_remote_camera), stride);
size_t size = offset + nbufs*stride;
if (offset != BUFFERS_OFFSET) {
tao_store_error(__func__, TAO_ASSERTION_FAILED);
return NULL;
}
// Allocate remote shared object.
tao_remote_camera* cam = (tao_remote_camera*)tao_remote_object_create(
owner, TAO_REMOTE_CAMERA, nbufs, offset, stride, size, flags);
if (cam == NULL) {
return NULL;
}
// Instanciate object.
tao_camera_info_initialize(&cam->info);
tao_shmid* bufs = get_bufs(cam);
for (long i = 0; i < nbufs; ++i) {
bufs[i] = TAO_BAD_SHMID;
}
for (long i = 0; i < 4; ++i) {
cam->preproc[i] = TAO_BAD_SHMID;
}
return cam;
}
tao_shmid tao_remote_camera_get_image_shmid(
tao_remote_camera* cam,
tao_serial serial)
{
// Check arguments.
if (cam == NULL) {
tao_store_error(__func__, TAO_BAD_ADDRESS);
return TAO_BAD_SHMID;
}
if (serial < 1) {
tao_store_error(__func__, TAO_BAD_SERIAL);
return TAO_BAD_SHMID;
}
const tao_shmid* bufs = get_bufs(cam);
tao_shmid shmid = bufs[(serial - 1)%cam->base.nbufs];
if (shmid == TAO_BAD_SHMID) {
tao_store_error(__func__, TAO_NO_DATA);
}
return shmid;
}
tao_serial tao_remote_camera_wait_image(
tao_remote_camera* cam,
tao_serial serial,
double secs)
{
return tao_remote_object_wait_serial(
tao_remote_object_cast(cam), serial, secs);
}
tao_status tao_remote_camera_start(
tao_remote_camera* cam,
const tao_camera_config* cfg,
double secs)
{
// Check arguments. Manage to use the current configuration if caller does
// not provide a configuration.
if (cam == NULL) {
tao_store_error(__func__, TAO_BAD_ADDRESS);
return TAO_ERROR;
}
if (cfg == NULL) {
cfg = &cam->info.config;
}
// Attempt to lock the remote camera and wait for it becomes ready for a
// new command.
tao_status status = tao_remote_object_lock_for_command(
tao_remote_object_cast(cam), TAO_COMMAND_START, secs);
if (status == TAO_OK) {
// Server is ready to accept a new command. Copy configuration to
// start with as the next configuration and unlock the ressources.
memcpy(&cam->nxtcfg, cfg, sizeof(*cfg));
if (tao_remote_camera_unlock(cam) != TAO_OK) {
status = TAO_ERROR;
}
}
return status;
}
tao_status tao_remote_camera_stop(
tao_remote_camera* cam,
double secs)
{
return tao_remote_object_send_simple_command(
tao_remote_object_cast(cam), TAO_COMMAND_STOP, secs);
}
tao_status tao_remote_camera_abort(
tao_remote_camera* cam,
double secs)
{
return tao_remote_object_send_simple_command(
tao_remote_object_cast(cam), TAO_COMMAND_ABORT, secs);
}
tao_status tao_remote_camera_kill(
tao_remote_camera* cam,
double secs)
{
return tao_remote_object_send_simple_command(
tao_remote_object_cast(cam), TAO_COMMAND_KILL, secs);
}
#define GETTER(type, path, member, def) \
type tao_remote_camera_get_##member( \
const tao_remote_camera* cam) \
{ \
return (cam != NULL ? cam->path.member : (def)); \
}
GETTER(long, info, sensorwidth, 0)
GETTER(long, info, sensorheight, 0)
GETTER(long, info.config.roi, xbin, 0)
GETTER(long, info.config.roi, ybin, 0)
GETTER(long, info.config.roi, xoff, 0)
GETTER(long, info.config.roi, yoff, 0)
GETTER(long, info.config.roi, width, 0)
GETTER(long, info.config.roi, height, 0)
GETTER(double, info.config, framerate, 0.0)
GETTER(double, info.config, exposuretime, 0.0)
GETTER(tao_eltype, info.config, pixeltype, TAO_UINT8)
GETTER(tao_encoding, info.config, sensorencoding, TAO_ENCODING_UNKNOWN)
GETTER(tao_encoding, info.config, bufferencoding, TAO_ENCODING_UNKNOWN)
//FIXME: GETTER(tao_state, info, state, TAO_STATE_KILLED)
#undef GETTER
// Generic shared object methods.
#define TYPE remote_camera
#define MAGIC TAO_REMOTE_CAMERA
#define IS_REMOTE_OBJECT 1
#include "./shared-methods.c"
......@@ -18,6 +18,7 @@
#include <tao-remote-objects.h>
#include <tao-rwlocked-objects.h>
#include <tao-shared-cameras.h>
#include <tao-remote-cameras.h>
#include <tao-remote-mirrors.h>
#include <stdbool.h>
......@@ -205,12 +206,14 @@ static inline bool tao_clamp_b(bool arg1_, bool arg2_, bool arg3_)
(obj), \
tao_shared_object *: (obj), \
tao_remote_object *: (tao_shared_object*)(obj), \
tao_remote_camera *: (tao_shared_object*)(obj), \
tao_remote_mirror *: (tao_shared_object*)(obj), \
tao_rwlocked_object *: (tao_shared_object*)(obj), \
tao_shared_array *: (tao_shared_object*)(obj), \
tao_shared_camera *: (tao_shared_object*)(obj), \
tao_shared_object const*: (obj), \
tao_remote_object const*: (tao_shared_object const*)(obj), \
tao_remote_camera const*: (tao_shared_object const*)(obj), \
tao_remote_mirror const*: (tao_shared_object const*)(obj), \
tao_rwlocked_object const*: (tao_shared_object const*)(obj), \
tao_shared_array const*: (tao_shared_object const*)(obj), \
......@@ -250,8 +253,10 @@ static inline bool tao_clamp_b(bool arg1_, bool arg2_, bool arg3_)
_Generic( \
(obj), \
tao_remote_object *: (obj), \
tao_remote_camera *: (tao_remote_object*)(obj), \
tao_remote_mirror *: (tao_remote_object*)(obj), \
tao_remote_object const*: (obj), \
tao_remote_camera const*: (tao_remote_object const*)(obj), \
tao_remote_mirror const*: (tao_remote_object const*)(obj))
#endif /* TAO_DOXYGEN_ */
......@@ -261,6 +266,7 @@ static inline bool tao_clamp_b(bool arg1_, bool arg2_, bool arg3_)
#define TAO_ANY_OBJECT_METHOD(verb, obj) \
_Generic( \
(obj), \
tao_remote_camera *: tao_remote_camera_##verb, \
tao_remote_mirror *: tao_remote_mirror_##verb, \
tao_remote_object *: tao_remote_object_##verb, \
tao_rwlocked_object*: tao_rwlocked_object_##verb, \
......@@ -322,6 +328,7 @@ static inline bool tao_clamp_b(bool arg1_, bool arg2_, bool arg3_)
tao_mutex *: tao_mutex_##verb, \
tao_shared_object*: tao_shared_object_##verb, \
tao_remote_object*: tao_remote_object_##verb, \
tao_remote_camera*: tao_remote_camera_##verb, \
tao_remote_mirror*: tao_remote_mirror_##verb)
/**
......@@ -494,6 +501,7 @@ static inline bool tao_clamp_b(bool arg1_, bool arg2_, bool arg3_)
tao_rwlock *: tao_rwlock_##verb, \
tao_shared_object *: tao_shared_object_##verb, \
tao_remote_object *: tao_remote_object_##verb, \
tao_remote_camera *: tao_remote_camera_##verb, \
tao_remote_mirror *: tao_remote_mirror_##verb, \
tao_rwlocked_object*: tao_rwlocked_object_##verb, \
tao_shared_camera *: tao_shared_camera_##verb, \
......
// tao-remote-cameras-private.h -
//
// Private definitions for remote cameras.
//
//-----------------------------------------------------------------------------
//
// This file if part of TAO real-time software licensed under the MIT license
// (https://git-cral.univ-lyon1.fr/tao/tao-rt).
//
// Copyright (C) 2018-2022, Éric Thiébaut.
#ifndef TAO_REMOTE_CAMERAS_PRIVATE_H_
#define TAO_REMOTE_CAMERAS_PRIVATE_H_ 1
#include <tao-remote-cameras.h>
#include <tao-remote-objects-private.h>
TAO_BEGIN_DECLS
/**
* @brief Remote camera information.
*
* @ingroup RemoteCameras
*
* This structure describes the shared data storing the resources of a remote
* camera. After querying the shared memory identifier to the server (the
* frame grabber), clients can attach this shared data part with
* tao_remote_camera_attach(). When a client no longer needs this shared data,
* it shall call tao_remote_camera_detach().
*
* This structure **must** be considered as read-only by the clients and
* information provided by this structure is only valid as long as the client
* locks this shared structure by calling tao_remote_camera_lock() and until
* the client unlock the structure by calling tao_remote_camera_unlock().
* Beware to not call tao_remote_camera_detach() while the shared data is
* locked by the caller.
*
* If @n serial > 0, the index in the list of shared arrays memorized by the
* virtual frame-grabber owning the remote camera is given by:
*
* ~~~~~{.c}
* index = (serial - 1) % nbufs
* ~~~~~
*
*/
struct tao_remote_camera_ {
tao_remote_object base;///< Shared object backing the storage of the
/// structure.
tao_camera_info info;///< Camera information.
tao_camera_config nxtcfg;///< Next configuration.
tao_shmid preproc[4];///< Shared memory identifiers of shared arrays
/// storing pre-processing parameters. It is
/// assumed that clients can only change the
/// contents of these arrays while owning an
/// exclusive access to the remote camera.
/// Pre-processing parameters are distinct arrays
/// for optimal memory alignment.
};
TAO_END_DECLS
#endif // TAO_REMOTE_CAMERAS_PRIVATE_H_
This diff is collapsed.
......@@ -105,7 +105,7 @@ typedef enum tao_object_type_ {
// 3rd generation types:
TAO_SHARED_ARRAY = (TAO_RWLOCKED_OBJECT| 1),///< Shared multi-dimensional array.
TAO_SHARED_CAMERA = (TAO_RWLOCKED_OBJECT| 2),///< Shared camera.
//TAO_REMOTE_CAMERA = (TAO_REMOTE_OBJECT | 2),///< Remote camera.
TAO_REMOTE_CAMERA = (TAO_REMOTE_OBJECT | 2),///< Remote camera.
TAO_REMOTE_MIRROR = (TAO_REMOTE_OBJECT | 3),///< Remote deformable mirror.
//TAO_REMOTE_SENSOR = (TAO_REMOTE_OBJECT | 4),///< Remote wavefront sensor.
} tao_object_type;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment