Skip to content

Commit

Permalink
add per-device documentation in the header files
Browse files Browse the repository at this point in the history
  • Loading branch information
imyxh committed Jun 18, 2024
1 parent 8989657 commit 4deebc5
Show file tree
Hide file tree
Showing 15 changed files with 360 additions and 54 deletions.
1 change: 0 additions & 1 deletion contrib/plot_square_of_doubles.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
# just a rudimentary plotting script to view square matrices
using ArgParse
using Plots; gr()
using FFTW

argset = ArgParseSettings()
@add_arg_table argset begin
Expand Down
2 changes: 1 addition & 1 deletion contrib/watch_udp_com.jl
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,6 @@ for i in 1:10000
))
end

close(sock)
close(sock1)


75 changes: 53 additions & 22 deletions devices/center_of_mass.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,61 @@
#include "anyloop.h"
#include "thread_pool.h"

/** aylp:center_of_mass
*
* types and units: `[T_MATRIX_UCHAR, U_ANY] -> [T_VECTOR, U_MINMAX]`
*
* This device breaks up an image into one or more regions, and calculates the
* center-of-mass coordinate of that image. For example, this device might be
* used with only one region to determine the center-of-mass coordinates of a
* beam on a camera, which can then be used to control a tip-tilt mirror to
* recenter said beam. This device is also used with many regions for getting
* error signals from a wavefront sensor.
*
* An example configuration for a wavefront sensor with 8x8-pixel subapertures:
*
* ```json
* {
* "uri": "anyloop:center_of_mass",
* "params": {
* "region_height": 8,
* "region_width": 8,
* "thread_count": 1
* }
* }
* ```
*
* Pipeline data is replaced with a vector of interleaved center-of-mass y and x
* coordinates (a vector of length 2N, where N is the number of regions of
* interest). For example, if the input has four regions of interest, the output
* will be [y1,x1,y2,x2,y3,x3,y4,x4] where each y,x is from -1 to 1, where 0
* means perfectly centered in the region of interest. It is assumed that the
* input is written in order of increasing x coordinate, then increasing y
* coordinate.
*
* Parameters:
* - `region_height` (integer) (required)
* - Height of each region to find the center of mass of. The image will be
* split up into regions of this height, from the top going down. Excess
* data will be ignored. Set this to 0 to set the region height to the
* logical height of the whole image.
* - `region_width` (integer) (required)
* - Width of each region to find the center of mass of. The image will be
* split up into regions of this width, from left to right. Excess data
* will be ignored. Set this to 0 to set the region width to the logical
* height of the whole image.
* - `thread_count` (integer) (optional)
* - Number of threads to use for the calculation. Set this to 1 (default)
* for no multithreading.
*/

struct aylp_center_of_mass_data {
/** Param: height of each region to find the center of mass of.
* The image will be split up into regions of this height, from the top
* going down. Excess data will be ignored. Set this to 0 to set the
* region height to the logical height of the whole image. */
// param: height of regions/subapertures
size_t region_height;

/** Param: width of each region to find the center of mass of.
* The image will be split up into regions of this width, from left to
* right. Excess data will be ignored. Set this to 0 to set the region
* height to the logical height of the whole image. */
// param: width of regions/subapertures
size_t region_width;

/** Param: number of threads to use for the calculation.
* Set this to 1 for no multithreading. */
// param; set to 1 for no multithreading
size_t thread_count;

// array of threads
pthread_t *threads;
// array of tasks
Expand All @@ -39,16 +77,9 @@ struct aylp_center_of_mass_data {
// initialize center_of_mass device
int center_of_mass_init(struct aylp_device *self);

/** Process center_of_mass device once per loop.
* Will replace pipeline data with a vector of interleaved center-of-mass y and x
* coordinates (a vector of length 2N, where N is the number of regions of
* interest). For example, if the input has four regions of interest, the output
* will be [y1,x1,y2,x2,y3,x3,y4,x4] where each y,x is from -1 to 1, where 0
* means perfectly centered in the region of interest. It is assumed that the
* input is of type AYLP_T_MATRIX_UCHAR, and is written in order of increasing x
* coordinate, then increasing y coordinate. */
// process center_of_mass device once per loop
int center_of_mass_process(struct aylp_device *self, struct aylp_state *state);
/** Multithreaded version of process function. */
// multithreaded version of process function
int center_of_mass_process_threaded(
struct aylp_device *self, struct aylp_state *state
);
Expand Down
13 changes: 13 additions & 0 deletions devices/delay.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,19 @@

#include "anyloop.h"

/** aylp:delay
*
* types and units: `[T_ANY, U_ANY] -> [T_UNCHANGED, U_UNCHANGED]`
*
* This device pauses execution of the loop for a certain period of time.
*
* Parameters:
* - `s` (integer) (optional)
* - Number of seconds to delay (default 0).
* - `ns` (integer) (optional)
* - Number of nanoseconds to delay; must be less than 1E9 (default 0).
*/

// initialize delay device
int delay_init(struct aylp_device *self);

Expand Down
17 changes: 16 additions & 1 deletion devices/file_sink.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,24 @@
#define AYLP_DEVICES_FILE_SINK_H_

#include <stdio.h>

#include "anyloop.h"

/** aylp:file_sink
*
* types and units: `[T_ANY, U_ANY] -> [T_UNCHANGED, U_UNCHANGED]`
*
* This device writes the current pipeline state to an AYLP file. See
* [filetype.md](../doc/filetype.md) for documentation on the AYLP file format.
*
* Parameters:
* - `filename` (string) (required)
* - The filename to write the pipeline data to.
* - `flush` (boolean) (optional)
* - Whether or not to flush the output every iteration. Setting this may
* slightly hinder performance, but will ensure that anything reading the
* file is not waiting for a buffered write.
*/

struct aylp_file_sink_data {
// file to sink data to
FILE *fp;
Expand Down
8 changes: 8 additions & 0 deletions devices/logger.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@

#include "anyloop.h"

/** aylp:logger
*
* types and units: `[T_ANY, U_ANY] -> [T_UNCHANGED, U_UNCHANGED]`
*
* This device tries to print the current pipeline data to the console.
*
*/

// initialize logger device
int logger_init(struct aylp_device *self);

Expand Down
1 change: 0 additions & 1 deletion devices/matmul.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,6 @@ int matmul_init(struct aylp_device *self)
}


// TODO: test this
int matmul_process_mm(struct aylp_device *self, struct aylp_state *state)
{
struct aylp_matmul_data *data = self->device_data;
Expand Down
23 changes: 17 additions & 6 deletions devices/matmul.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,23 @@
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_vector.h>

/*
* param "filename":
* the aylp file to read a matrix from
* param "type":
* "vector" if we are multiplying matrix by vector,
* or "matrix" if we are multiplying matrix by matrix
/** aylp:matmul
*
* types and units: `[T_VECTOR|T_MATRIX, U_ANY] -> [T_UNCHANGED, U_UNCHANGED]`
*
* This device reads a matrix from a provided AYLP file, and multiplies the
* vector or matrix that is in the pipeline by the provided matrix. This is a
* simple but powerful device; depending on the matrix it is given, it could do
* basis conversions (e.g. Zernike transforms), wavefront reconstruction, etc.
* The only tricky part is deciding what matrix to feed it!
*
* Parameters:
* - `filename` (string) (required)
* - The filename of the AYLP file to read a matrix from.
* - `type` (string) (required)
* - "vector" if this device is to do matrix-vector multiplication (and thus
* input type is `T_VECTOR`), and "matrix" if this device is to do
* matrix-matrix multiplication (for input type `T_MATRIX`).
*/

struct aylp_matmul_data {
Expand Down
39 changes: 38 additions & 1 deletion devices/pid.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,46 @@
#define AYLP_DEVICES_PID_H_

#include <time.h>

#include "anyloop.h"

/** aylp:pid
*
* types and units: `[T_VECTOR|T_MATRIX, U_ANY] -> [T_UNCHANGED, U_UNCHANGED]`
*
* This device applies [PID](https://en.wikipedia.org/wiki/PID_controller) error
* correction, taking the pipeline state as error input and replacing it with
* the calculated correction.
*
* Let `x_0` be the current input, `x_1` be the input from last iteration of the
* loop, `dt` be the time in seconds that has elapsed since the previous
* iteration, `x_acc` be the accumulated total errors since the loop was
* started, and `y` be the output. Then this PID device more or less implements:
*
* ```
* y = - p*x_0 - i*x_acc - d*(x_0-x_1)/dt
* ```
*
* More precisely, it implements the above equation but clamping the total
* correction to the `clamp` parameter in magnitude, after first clamping the
* `x_acc` term the same way.
*
* Parameters:
* - `type` (string) (required)
* - "vector" if we are expecting `T_VECTOR` input, and "matrix" if we are
* expecting `T_MATRIX` input.
* - `p` (float) (optional)
* - Coefficent for proportional correction (see equation above). Defaults
* to 1.0.
* - `i` (float) (optional)
* - Coefficent for integral correction (see equation above). Default 0.0.
* - `d` (float) (optional)
* - Coefficent for derivative correction (see equation above). Default 0.0.
* - `clamp` (float) (optional)
* - What to clamp the correction to in magnitude. Will be applied first to
* `x_acc` and later to the whole correction. Useful to prevent the
* integral component from completely running away. Defaults to 1.0.
*/

struct aylp_pid_data {
// param type in ["vector", "matrix"]
aylp_type type;
Expand Down
99 changes: 99 additions & 0 deletions devices/poke.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,105 @@
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_vector.h>

/** aylp:poke
*
* types and units: `[T_VECTOR, U_MINMAX] -> [T_VECTOR, U_MINMAX]`
*
* This device generates a new *command vector* every iteration, and then reads
* in an associated *error vector* on the next iteration; these error vectors
* are then horizontally concatenated to form a *poke matrix*, which is then
* written to a file. As such, this device wants to be in the pipeline before a
* device that will actuate on the outputted command vectors, and after a device
* that will produce some error vector.
*
* Specifically, what this device will do, is generate command vectors that look
* like ...
*
* - iteration 1: [ 1, 0, 0, 0, ...]
* - iteration 2: [-1, 0, 0, 0, ...]
* - iteration 3: [ 0, 1, 0, 0, ...]
* - iteration 4: [ 0, -1, 0, 0, ...]
* - iteration 3: [ 0, 0, 1, 0, ...]
* - iteration 4: [ 0, 0, -1, 0, ...]
* - etc.
*
* ... and for every pair of iterations, it will read the two associated error
* vectors, subtract one from the other, divide by two, and copy the result into
* the corresponding column of the poke matrix. For example, let's say we have
* just a tip-tilt mirror that takes a two-element command vector, and some
* other set of devices that output the y,x coordinates of a spot on some
* sensor. aylp:poke might then do the following:
*
* 1. output [1, 0] as command vector;
* 2. read (e.g.) [0.26, 0.26] as error vector;
* 3. output [-1, 0] as command vector;
* 4. read [-0.24, -0.24] as error vector;
* 5. store [0.25, 0.25] as the first column of the poke matrix;
* 6. output [0, 1] as command vector;
* 7. read [0.26, -0.26] as error vector;
* 8. output [0, -1] as command vector;
* 9. read [-0.24, 0.24] as error vector;
* 10. store [0.25, -0.25] as the first column of the poke matrix.
*
* The final poke matrix in this hypothetical case would then be
*
* ```
* [ 0.25 0.25
* 0.25 -0.25 ]
* ```
*
* Thus, we would be able to tell that the tip/tilt axes of the mirror were not
* perfectly aligned to those of whatever instrument was reporting the tip/tilt
* error, and this poke matrix could be used to help correct that.
*
* Here's an example of a stripped-down configuration to generate a poke matrix
* for a wavefront sensor and a deformable mirror:
*
* ```json
* { "pipeline": [
* {
* "_comment": "this is a wavefront sensor that outputs an image matrix",
* "uri": "file:aylp_basler_fgsdk.so",
* "params": {
* "width": 80,
* "height": 80
* }
* },
* {
* "uri": "anyloop:center_of_mass",
* "params": {
* "region_height": 8,
* "region_width": 8,
* "thread_count": 1
* }
* },
* {
* "uri": "anyloop:poke",
* "params": {
* "n_act": 97,
* "filename": "poke.aylp"
* }
* },
* {
* "_comment": "this is a deformable mirror device",
* "uri": "file:aylp_asdk_dm.so",
* "params": {
* "_comment": "whatever parameters needed for the deformable mirror"
* }
* }
* ]}
* ```
*
* See [command.md](../doc/command.md) for more information.
*
* Parameters:
* - `n_act` (integer) (required)
* - The count of actuators in our poking device, or in other words, the
* length of our poke matrix.
* - `filename` (string) (required)
* - The filename to use when saving the poke matrix as an AYLP file.
*/

struct aylp_poke_data {
// poke matrix
gsl_matrix *poke_matrix;
Expand Down
13 changes: 13 additions & 0 deletions devices/stop_after_count.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,19 @@

#include "anyloop.h"

/** aylp:stop_after_count
*
* types and units: `[T_ANY, U_ANY] -> [T_UNCHANGED, U_UNCHANGED]`
*
* This device stops the loop after a certain number of iterations.
*
* Parameters:
* - `count` (integer) (required)
* - The number of iterations to stop after (e.g. count = 1 means every
* device in the loop will run once).
*/


// initialize count device
int stop_after_count_init(struct aylp_device *self);

Expand Down
Loading

0 comments on commit 4deebc5

Please sign in to comment.