Commit 8802e9cf authored by Éric Thiébaut's avatar Éric Thiébaut
Browse files

Change API of tao_remote_mirror_set_reference, new tao_remote_mirror_set_perturbation

parent df70da03
......@@ -237,12 +237,12 @@ static tao_serial send_simple_command(
// Attempt to lock the remote mirror and wait for it becomes ready for a
// new command.
tao_serial num = tao_remote_object_lock_for_command(
tao_serial cmdnum = tao_remote_object_lock_for_command(
tao_remote_object_cast(obj), cmd, secs);
if (num > 0 && tao_remote_mirror_unlock(obj) != TAO_OK) {
num = -1;
if (cmdnum > 0 && tao_remote_mirror_unlock(obj) != TAO_OK) {
cmdnum = -1;
}
return num;
return cmdnum;
}
tao_serial tao_remote_mirror_reset(
......@@ -259,46 +259,73 @@ tao_serial tao_remote_mirror_kill(
return send_simple_command(__func__, obj, TAO_COMMAND_KILL, secs);
}
tao_serial tao_remote_mirror_set_reference(
static tao_serial change_actuators_offsets(
const char* func,
tao_remote_mirror* obj,
const double* vals,
long nvals,
double secs)
double secs,
tao_serial* datnum,
long which)
{
// Check arguments.
if (obj == NULL || vals == NULL) {
tao_store_error(__func__, TAO_BAD_ADDRESS);
tao_store_error(func, TAO_BAD_ADDRESS);
return -1;
}
if (nvals != obj->nacts) {
tao_store_error(__func__, TAO_BAD_SIZE);
tao_store_error(func, TAO_BAD_SIZE);
return -1;
}
// Prepare for i/o.
double* dest = get_values(obj);
double* dest = get_values(obj) + nvals*which;
// Wait until server be ready for a new command.
tao_serial num = tao_remote_object_lock_for_command(
tao_serial cmdnum = tao_remote_object_lock_for_command(
tao_remote_object_cast(obj), TAO_COMMAND_CONFIG, secs);
if (num > 0) {
if (cmdnum > 0) {
// The server is ready for a new command.
//
// 1. Copy the reference commands in the shared resources.
if (datnum != NULL) {
// The effects of this command will be effective in the next
// data-frame.
*datnum = tao_max(obj->base.serial + 1, 1);
}
// Copy the values in the shared resources.
memcpy(dest, vals, nvals*sizeof(double));
//
// 2. There is nothing else to be done by the server, so we increment
// our-self the command counter and clear the pending command to not
// bother the server.
obj->base.ncmds = num;
// There is nothing else to be done by the server, so we increment
// our-self the command counter and clear the pending command to not
// bother the server and let anyone send a set of actuators commands.
obj->base.ncmds = cmdnum;
obj->base.command = TAO_COMMAND_NONE;
//
// 3. Finally unlock the resources.
// Finally unlock the resources.
if (tao_remote_mirror_unlock(obj) != TAO_OK) {
num = -1;
cmdnum = -1;
}
}
return num;
return cmdnum;
}
tao_serial tao_remote_mirror_set_reference(
tao_remote_mirror* obj,
const double* vals,
long nvals,
double secs,
tao_serial* datnum)
{
return change_actuators_offsets(
__func__, obj, vals, nvals, secs, datnum, 0);
}
tao_serial tao_remote_mirror_set_perturbation(
tao_remote_mirror* obj,
const double* vals,
long nvals,
double secs,
tao_serial* datnum)
{
return change_actuators_offsets(
__func__, obj, vals, nvals, secs, datnum, 1);
}
tao_serial tao_remote_mirror_send_commands(
......@@ -307,7 +334,7 @@ tao_serial tao_remote_mirror_send_commands(
long nvals,
tao_serial mark,
double secs,
tao_serial* serial)
tao_serial* datnum)
{
// Check arguments.
if (obj == NULL || vals == NULL) {
......@@ -320,34 +347,32 @@ tao_serial tao_remote_mirror_send_commands(
}
// Prepare for i/o.
double* dest = get_values(obj) + 2*obj->nacts;
double* dest = get_values(obj) + 2*nvals;
// Wait until server ready for a new command.
tao_serial num = tao_remote_object_lock_for_command(
tao_serial cmdnum = tao_remote_object_lock_for_command(
tao_remote_object_cast(obj), TAO_COMMAND_SEND, secs);
if (num > 0) {
// Server was ready for the new command. Get next serial number, copy
// actuators values, and unlock object.
tao_serial next = obj->base.serial + 1;
if (next < 1) {
next = 0;
}
if (serial != NULL) {
*serial = next;
if (cmdnum > 0) {
// Server was ready for the new command.
if (datnum != NULL) {
// The effects of this command will be effective in the next
// data-frame.
*datnum = tao_max(obj->base.serial + 1, 1);
}
// Copy actuators values, and unlock object.
memcpy(dest, vals, nvals*sizeof(double));
obj->mark = mark;
if (tao_remote_mirror_unlock(obj) != TAO_OK) {
num = -1;
cmdnum = -1;
}
}
return num;
return cmdnum;
}
// FIXME: check running?
tao_status tao_remote_mirror_fetch_data(
const tao_remote_mirror* obj,
tao_serial serial,
tao_serial datnum,
double* vals_0,
double* vals_1,
double* vals_2,
......@@ -370,7 +395,7 @@ tao_status tao_remote_mirror_fetch_data(
tao_store_error(__func__, TAO_BAD_SIZE);
return TAO_ERROR;
}
if (serial < 1) {
if (datnum < 1) {
tao_store_error(__func__, TAO_BAD_SERIAL);
return TAO_ERROR;
}
......@@ -378,12 +403,12 @@ tao_status tao_remote_mirror_fetch_data(
// Fetch the data.
size_t nbytes = obj->nacts*sizeof(double);
double* data;
const tao_dataframe_header* header = fetch_frame(obj, serial, &data);
const tao_dataframe_header* header = fetch_frame(obj, datnum, &data);
tao_serial frame_serial = atomic_load(&header->serial);
if (frame_serial == serial) {
if (frame_serial == datnum) {
// Copy the contents of the data-frame now.
if (info != NULL) {
info->serial = serial;
info->serial = frame_serial;
info->mark = header->mark;
info->time = header->time;
}
......@@ -401,12 +426,12 @@ tao_status tao_remote_mirror_fetch_data(
}
// Check that data-frame has not been overwritten in the mean time.
frame_serial = atomic_load(&header->serial);
if (frame_serial == serial) {
if (frame_serial == datnum) {
return TAO_OK;
}
frame_serial = -1; // data has been overwritten
} else {
frame_serial = (frame_serial < serial ? 0 : -1);
frame_serial = (frame_serial < datnum ? 0 : -1);
}
// The requested frame is either to new (timeout) or too old (overwrite).
......@@ -500,7 +525,7 @@ tao_status tao_remote_mirror_run_loop(
command_name, ops->name);
}
if (command == TAO_COMMAND_RESET) {
// A "reset" is strictly equivalent to a "send" but with all
// A "reset" is rigorously equivalent to a "send" but with all
// requested actuators commands set to zero.
memset(cmd_2, 0, nacts*sizeof(double));
}
......
......@@ -560,22 +560,22 @@ int TAO_XJOIN3(tao_,TYPE,_is_alive)(
#if REMOTE_OBJECT > 1 // Is it a sub-type of tao_remote_object?
tao_serial TAO_XJOIN3(tao_,TYPE,_wait_output)(
TAO_XJOIN2(tao_,TYPE)* obj,
tao_serial num,
tao_serial datnum,
double secs)
{
return tao_remote_object_wait_output(
tao_remote_object_cast(obj), num, secs);
tao_remote_object_cast(obj), datnum, secs);
}
#endif
#if REMOTE_OBJECT > 1 // Is it a sub-type of tao_remote_object?
tao_status TAO_XJOIN3(tao_,TYPE,_wait_command)(
TAO_XJOIN2(tao_,TYPE)* obj,
tao_serial num,
tao_serial cmdnum,
double secs)
{
return tao_remote_object_wait_command(
tao_remote_object_cast(obj), num, secs);
tao_remote_object_cast(obj), cmdnum, secs);
}
#endif
......
......@@ -49,21 +49,24 @@ TAO_BEGIN_DECLS
* by calling tao_remote_mirror_get_reference() and which is set by
* tao_remote_mirror_set_reference().
*
* - An internal buffer storing the requested commands which can be retrieved
* by calling tao_remote_mirror_get_requested_commands() and which is set by
* tao_remote_mirror_send_commands().
* - An internal buffer storing perturbations of the actuators commands and
* which is set by tao_remote_mirror_set_perturbation().
*
* - An internal buffer storing the actual commands which can be retrieved by
* calling tao_remote_mirror_get_actual_commands() and which is set by
* tao_remote_mirror_send_commands() after the commands have been applied to
* the device.
* - An internal buffer storing the requested commands and which is set by
* tao_remote_mirror_send_commands().
*
* - A cyclic list of output buffers storing an history of the commands
* actually applied to the mirror. Waiting for a given output buffer is done
* by calling tao_remote_mirror_wait_output() and retrieving the contents of
* an output buffer is done by calling tao_remote_mirror_fetch_data().
*
* Note that commands are relative to the reference values.
* Commands sent to the deformable mirror device are the sum of the requested
* comands, of the reference commands, and of the perturbations of the
* commands. Since the deformable mirror may has limitations on the possible
* actuators commands, the actual commands applied to the deformable mirror may
* be different than the requested ones. All this 4 sets of actuators commands
* can be retrieved in the output buffers published by the server owning the
* deformable mirror.
*/
typedef struct tao_remote_mirror_ tao_remote_mirror;
......@@ -649,7 +652,9 @@ extern double *tao_remote_mirror_get_reference(
*
* This function manages to send a "*reset*" command to a remote deformable
* mirror. The remote deformable mirror must not have been locked by the
* caller.
* caller. Calling this function is rigorously equivalent to calling
* tao_remote_mirror_send_commands() with all requested actuatirs commands set
* to zero.
*
* @param obj Pointer to remote deformable mirror in caller's address space.
*
......@@ -681,32 +686,89 @@ extern tao_serial tao_remote_mirror_kill(
double secs);
/**
* Set the reference commands of a remote deformable mirror.
* Set the reference for the subsequent actuators commands applied to a
* deformable mirror.
*
* This function waits for the remote deformable mirror `obj` to become idle and
* then sets the reference values for the actuators commands. These values
* will be used for the subsequent actuators commands applied with
* tao_remote_mirror_send_commands().
* This function waits for the remote deformable mirror `obj` to become ready
* for a new command and then sets the reference values for the actuators
* commands. These values will be used for the subsequent actuators commands
* applied with tao_remote_mirror_send_commands() until another call to
* tao_remote_mirror_set_reference() by any connected client.
*
* The remote deformable mirror must not have been locked by the caller.
*
* @param obj Pointer to remote deformable mirror in caller's address space.
* @param obj Pointer to remote deformable mirror in caller's address
* space.
*
* @param vals The reference values.
* @param vals The reference command values.
*
* @param nvals The number of values in `vals`, must be equal to the number of
* actuators.
* @param nvals The number of values in `vals`, must be equal to the number
* of actuators.
*
* @param secs Maximum amount of time to wait (in seconds).
* @param secs Maximum amount of time to wait (in seconds).
*
* @param datnum Address to store the serial number of the data-frame in the
* deformable mirror output telemetry where the command will be
* effective (not used if `NULL`). The caller may wait on
* this value with tao_remote_mirror_wait_output() to wait for
* the first data-frame affected by the values in `vals`.
*
* @return The serial number of the "*set reference*" command, 0 if the command
* cannot be sent before the time limit, -1 in case of error.
* cannot be sent before the time limit, -1 in case of error. If a
* positive value is returned, the caller may wait on this value with
* tao_remote_mirror_wait_command() to ensure that the new reference
* has been taken into account.
*/
extern tao_serial tao_remote_mirror_set_reference(
tao_remote_mirror* obj,
const double* vals,
long nvals,
double secs);
double secs,
tao_serial* datnum);
/**
* Set a perturbation for the next actuators commands applied to a
* deformable mirror.
*
* This function waits for the remote deformable mirror `obj` to become ready
* for a new command and then sets the values of a perturbation of the
* actuators commands. These values will be used for the next actuators
* commands applied with tao_remote_mirror_send_commands() and cleared when
* this latter command is excuted.
*
* If another perturbation has been set before but not yet applied, the new
* perturbation values replace the old ones.
*
* The remote deformable mirror must not have been locked by the caller.
*
* @param obj Pointer to remote deformable mirror in caller's address
* space.
*
* @param vals The values of the perturbation of the actuators commands.
*
* @param nvals The number of values in `vals`, must be equal to the number
* of actuators.
*
* @param secs Maximum amount of time to wait (in seconds).
*
* @param datnum Address to store the serial number of the data-frame in the
* deformable mirror output telemetry where the effects of this
* command will be effective (not used if `NULL`). The caller
* may wait on this value with tao_remote_mirror_wait_output()
* to wait for the data-frame affected by the values in `vals`.
*
* @return The serial number of the "*set perturbation*" command, 0 if the
* command cannot be sent before the time limit, -1 in case of error.
* If a positive value is returned, the caller may wait on this value
* with tao_remote_mirror_wait_command() to ensure that the new
* reference has been taken into account.
*/
extern tao_serial tao_remote_mirror_set_perturbation(
tao_remote_mirror* obj,
const double* vals,
long nvals,
double secs,
tao_serial* datnum);
/**
* Set the actuators of a remote deformable mirror.
......@@ -719,20 +781,22 @@ extern tao_serial tao_remote_mirror_set_reference(
* @warning The remote deformable mirror must not have been locked by the
* caller.
*
* @param obj Pointer to remote deformable mirror in caller's address space.
* @param obj Pointer to remote deformable mirror in caller's address
* space.
*
* @param vals The actuator command values.
* @param vals The actuator command values.
*
* @param nvals The number of values in `vals`, must be equal to the number of
* actuators.
* @param nvals The number of values in `vals`, must be equal to the number
* of actuators.
*
* @param mark The number associated with the resulting data-frame in the
* deformable mirror telemetry.
* @param mark The number associated with the resulting data-frame in the
* deformable mirror telemetry.
*
* @param secs Maximum amount of time to wait (in seconds).
* @param secs Maximum amount of time to wait (in seconds).
*
* @param serial Address to store the serial number of the commands in the
* deformable mirror telemetry (not used if `NULL`).
* @param datnum Address to store the serial number of the data-frame in the
* deformable mirror output telemetry where the command will be
* effective (not used if `NULL`).
*
* @return The serial number of the "*send*" command, 0 if the command cannot
* be sent before the time limit, -1 in case of error.
......@@ -743,7 +807,7 @@ extern tao_serial tao_remote_mirror_send_commands(
long nvals,
tao_serial mark,
double secs,
tao_serial* serial);
tao_serial* datnum);
/**
* Wait for a given command to have been processed.
......@@ -756,7 +820,7 @@ extern tao_serial tao_remote_mirror_send_commands(
* @param obj Pointer to a remote mirror attached to the address space of
* the caller.
*
* @param num The serial number of the command to wait for.
* @param cmdnum The serial number of the command to wait for.
*
* @param secs Maximum amount of time to wait (in seconds).
*
......@@ -765,7 +829,7 @@ extern tao_serial tao_remote_mirror_send_commands(
*/
extern tao_status tao_remote_mirror_wait_command(
tao_remote_mirror* obj,
tao_serial num,
tao_serial cmdnum,
double secs);
/**
......@@ -786,11 +850,11 @@ extern tao_status tao_remote_mirror_wait_command(
* size_t size = data->nacts*sizeof(double);
* double* refs = malloc(size);
* double* cmds = malloc(size);
* tao_serial serial = tao_remote_mirror_wait_output(dm, 0, 3.2);
* tao_serial datnum = tao_remote_mirror_wait_output(dm, 0, 3.2);
* if (serial > 0) {
* tao_dataframe_info info;
* tao_status status = tao_remote_mirror_fetch_data(
* dm, serial, refs, cmds, data->nacts, &info);
* dm, datnum, refs, cmds, data->nacts, &info);
* if (status == TAO_OK) {
* // Process data-frame.
* ....
......@@ -803,23 +867,23 @@ extern tao_status tao_remote_mirror_wait_command(
*
* @param obj Pointer to remote mirror in caller's address space.
*
* @param serial The serial number of the frame to wait for. If less or
* @param datnum The serial number of the data-frame to wait for. If less or
* equal zero, the next frame is waited for.
*
* @param secs Maximum number of seconds to wait.
*
* @return A strictly positive number which is the serial number of the
* requested frame, `0` if the requested frame is not available before
* the time limit (i.e. timeout), `-1` if the requested frame is too
* old (it has been overwritten by some newer frames or it is beyond
* the last available frame), `-2` if the server has been killed and
* the requested frame is beyond the last available one, or `-3` in
* requested data-frame, `0` if the requested frame is not available
* before the time limit (i.e. timeout), `-1` if the requested frame is
* too old (it has been overwritten by some newer frames or it is
* beyond the last available frame), `-2` if the server has been killed
* and the requested frame is beyond the last available one, or `-3` in
* case of failure. In the latter case, error details are reflected by
* the caller's last error.
*/
extern tao_serial tao_remote_mirror_wait_output(
tao_remote_mirror* obj,
tao_serial serial,
tao_serial datnum,
double secs);
/**
......@@ -837,7 +901,7 @@ extern tao_serial tao_remote_mirror_wait_output(
*
* @param obj Pointer to remote mirror in caller's address space.
*
* @param num Serial number of the data-frame to fetch. This value is
* @param datnum Serial number of the data-frame to fetch. This value is
* used to assert that the data-frame has not been overwritten
* in the mean time. Typically, this value has been obtained
* by calling tao_remote_mirror_wait_output().
......
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