Update comments for Doxygen. Move old, unused files to the testing folder.
authorJeremy Tan <[email protected]>
Sun, 3 Nov 2013 10:02:14 +0000 (18:02 +0800)
committerJeremy Tan <[email protected]>
Sun, 3 Nov 2013 10:02:14 +0000 (18:02 +0800)
35 files changed:
server/Makefile
server/actuator.c
server/bbb_pin.c
server/bbb_pin.h
server/bbb_pin_defines.h
server/common.h
server/control.c
server/control.h
server/data.c
server/data.h
server/dilatometer.c [deleted file]
server/dilatometer.h [deleted file]
server/fastcgi.c
server/fastcgi.h
server/image.c
server/image.h
server/interferometer.c [deleted file]
server/interferometer.h [deleted file]
server/intertest.sh [deleted file]
server/microscope.c [deleted file]
server/microscope.h [deleted file]
server/pin_test.c
server/sensor.c
server/sensor.h
server/stream.c [deleted file]
testing/Camera/dilatometer/Readme.md [new file with mode: 0644]
testing/Camera/dilatometer/dilatometer.c [new file with mode: 0644]
testing/Camera/dilatometer/dilatometer.h [new file with mode: 0644]
testing/Camera/dilatometer/microscope.c [new file with mode: 0644]
testing/Camera/dilatometer/microscope.h [new file with mode: 0644]
testing/Camera/dilatometer/stream.c [new file with mode: 0644]
testing/interferometer/Readme.md [new file with mode: 0644]
testing/interferometer/interferometer.c [new file with mode: 0644]
testing/interferometer/interferometer.h [new file with mode: 0644]
testing/interferometer/intertest.sh [new file with mode: 0755]

index 00ed880..10be3ec 100644 (file)
@@ -28,6 +28,7 @@ microscope : microscope.o
 
 clean :
        make -C sensors clean
+       make -C actuators clean
        $(RM) $(BIN) $(BIN2)
        $(RM) *.o
 
index 7473485..7716318 100644 (file)
@@ -16,8 +16,12 @@ static Actuator g_actuators[ACTUATORS_MAX];
 /** 
  * Add and initialise an Actuator
  * @param name - Human readable name of the actuator
- * @param read - Function to call whenever the actuator should be read
+ * @param user_id - Caller specified ID to be associated with this actuator
+ * @param set - Function to call whenever the actuator should be set
  * @param init - Function to call to initialise the actuator (may be NULL)
+ * @param cleanup - Function to call to deinitialise the actuator (may be NULL)
+ * @param sanity - Function to call to check that a user specified value is sane (may be NULL)
+ * @param initial_value - The initial value to set the actuator to
  * @returns Number of actuators added so far
  */
 int Actuator_Add(const char * name, int user_id, SetFn set, InitFn init, CleanFn cleanup, SanityFn sanity, double initial_value)
@@ -242,6 +246,7 @@ void Actuator_SetControl(Actuator * a, ActuatorControl * c)
  * Set an Actuator value
  * @param a - The Actuator
  * @param value - The value to set
+ * @param record - Whether or not to record the value to the Actuator's DataFile.
  */
 void Actuator_SetValue(Actuator * a, double value, bool record)
 {
@@ -275,8 +280,8 @@ void Actuator_SetValue(Actuator * a, double value, bool record)
 /**
  * Helper: Begin Actuator response in a given format
  * @param context - the FCGIContext
+ * @param a - the actuator to begin a response for
  * @param format - Format
- * @param id - ID of Actuator
  */
 void Actuator_BeginResponse(FCGIContext * context, Actuator * a, DataFormat format)
 {
@@ -298,7 +303,7 @@ void Actuator_BeginResponse(FCGIContext * context, Actuator * a, DataFormat form
 /**
  * Helper: End Actuator response in a given format
  * @param context - the FCGIContext
- * @param id - ID of the Actuator
+ * @param a - the actuator to end a response for
  * @param format - Format
  */
 void Actuator_EndResponse(FCGIContext * context, Actuator * a, DataFormat format)
@@ -458,6 +463,11 @@ Actuator * Actuator_Identify(const char * name)
        return NULL;
 }
 
+/**
+ * Returns the last DataPoint that is currently available.
+ * @param id - The actuator ID for which to retrieve data from
+ * @return The last DataPoint
+ */
 DataPoint Actuator_LastData(int id)
 {
        Actuator * a = &(g_actuators[id]);
index bd31365..199706f 100644 (file)
@@ -334,6 +334,7 @@ void ADC_Unexport(int pin)
 /**
  * Set a GPIO pin
  * @param pin - The pin to set. MUST have been exported before calling this function.
+ * @param value - The value to set the GPIO pin to.
  */
 bool GPIO_Set(int pin, bool value)
 {
index 658b95a..14bc7eb 100644 (file)
@@ -31,6 +31,7 @@ extern bool PWM_Set(int pin, bool polarity, long period, long duty); // period a
 extern bool PWM_Stop(int pin);
 
 #else
+//! @cond Doxygen_Suppress
 //Horrible hacks to silence gcc when compiling on systems that are not the BBB
 extern bool True_Stub(int arg, ...);
 extern bool ADC_Read_Stub(int *val, ...);
@@ -53,7 +54,7 @@ extern bool GPIO_Read_Stub(bool *val, ...);
 #define PWM_Set(pin, polarity, period, duty) True_Stub((int)pin, polarity, period, duty)
 #define PWM_Stop(pin) True_Stub((int)pin) 
 //yuck
-
+//! @endcond
 #endif //_BBB
 
 #endif //_BBB_PIN_H
index cb77dac..7ccda87 100644 (file)
@@ -10,7 +10,6 @@
 #define BBB_PIN_COUNT 92
 
 /** GPIO0 defines **/
-
 #define GPIO0_1 1
 #define GPIO0_2 2 // Used for PWM
 #define GPIO0_3 3 // Used for PWM
@@ -136,13 +135,16 @@ extern const unsigned char g_pin_index_to_gpio[GPIO_NUM_PINS];
 #define ADC5 5
 #define ADC6 6
 #define ADC7 7
+/** The maximum voltage input to the ADC **/
 #define ADC_VOLTAGE_MAX 1800
+/** The maximum raw value from the ADC **/
 #define ADC_RAW_MAX (2 << ADC_BITS)
+/** Converts the raw ADC value to a voltage in millivolts **/
 #define ADC_TO_MVOLTS(x) ((double)((x)/2 << ADC_BITS) * (double)ADC_VOLTAGE_MAX)
 
 /** Number of ADC pins **/
 #define ADC_NUM_PINS 8
-
+/** The path to the ADCs on the BBB **/
 #define ADC_DEVICE_PATH "/sys/bus/iio/devices/iio:device0/"
 
 /** PWM names to sysfs numbers **/
index 0875b34..5eee7cc 100644 (file)
@@ -51,7 +51,7 @@
                                                                                (tv)->tv_nsec = ((value) - (int)(value))*1e9; \
                                                                        }
 
-extern bool PathExists(const char * path);
+//extern bool PathExists(const char * path);
 extern bool DirExists(const char * path);
 
 
index f81ea00..280a132 100644 (file)
 #include <sys/types.h>
 #include <sys/stat.h>
 
+/**
+ * Control state information (start/stop/pause etc)
+ */
 typedef struct ControlData {
-       ControlModes current_mode;
-       pthread_mutex_t mutex;
-       struct timespec start_time;
-       char user_name[31]; // The user who owns the currently running experiment
-       char experiment_dir[BUFSIZ]; //Directory for experiment
-       char experiment_name[BUFSIZ];
+       ControlModes current_mode; /** Current experiment mode **/
+       pthread_mutex_t mutex; /** Mutex to serialise access to control methods **/
+       struct timespec start_time; /** Start time of current experiment **/
+       char user_name[31]; /** The user who owns the currently running experiment **/
+       char experiment_dir[BUFSIZ]; /** Directory for experiment **/
+       char experiment_name[BUFSIZ]; /** Name of the current experiment **/
 } ControlData;
 
 ControlData g_controls = {CONTROL_STOP, PTHREAD_MUTEX_INITIALIZER, {0}};
 
+/**
+ * Determines if a directory exists or not.
+ * @param path The path to check
+ * @return true iff the path exists
+ */
 bool DirExists(const char *path)
 {
        DIR *dir = opendir(path);
@@ -32,19 +40,9 @@ bool DirExists(const char *path)
        return false;
 }
 
-bool PathExists(const char *path) 
-{
-       FILE *fp = fopen(path, "r");
-       if (fp) {
-               fclose(fp);
-               return true;
-       }
-       return false;
-}
-
 /**
  * Lists all experiments for the current user.
- * @param The context to work in
+ * @param context The context to work in
  */
 void ListExperiments(FCGIContext *context) 
 {
@@ -260,7 +258,6 @@ const char* Control_SetMode(ControlModes desired_mode, void * arg)
 
 /**
  * Gets a string representation of the current mode
- * @param mode The mode to get a string representation of
  * @return The string representation of the mode
  */
 const char * Control_GetModeName() {
index 0dfdc47..e623033 100644 (file)
@@ -5,6 +5,10 @@
 #ifndef _CONTROL_H
 #define _CONTROL_H
 
+/** 
+ * The possible experiment control modes that the server can be in.
+ * At present, CONTROL_EMERGENCY largely does nothing. TODO: Fix this
+ */
 typedef enum ControlModes {
        CONTROL_START,
        CONTROL_PAUSE,
@@ -17,12 +21,12 @@ typedef enum ControlModes {
 #define INVALID_CHARACTERS "\"*/:<>?\\|. "
 /** The same as INVALID_CHARACTERS, except escaped for use in JSON strings **/
 #define INVALID_CHARACTERS_JSON "\\\"*/:<>?\\\\|. "
-
+/** The username of a user with no authentication (DEBUG ONLY) **/
 #define NOAUTH_USERNAME "_anonymous_noauth"
 
 extern void Control_Handler(FCGIContext *context, char *params);
 extern const char* Control_SetMode(ControlModes desired_mode, void * arg);
-extern ControlModes Control_GetMode();
+//extern ControlModes Control_GetMode();
 extern const char * Control_GetModeName();
 //extern bool Control_Lock();
 //extern void Control_Unlock();
index 19828bc..38eba83 100644 (file)
@@ -292,7 +292,7 @@ int Data_FindByTime(DataFile * df, double time_stamp, DataPoint * closest)
  * @param df - DataFile to access
  * @param start - Info about start_time param 
  * @param end - Info about end_time param
- * @param fmt - Info about format param
+ * @param format - Info about format param
  * @param current_time - Current time
  */
 void Data_Handler(DataFile * df, FCGIValue * start, FCGIValue * end, DataFormat format, double current_time)
index 0573c2e..188f5aa 100644 (file)
@@ -6,7 +6,7 @@
 #ifndef _DATAPOINT_H
 #define _DATAPOINT_H
 
-#define DATA_BUFSIZ 10 // Size to use for DataPoint buffers (TODO: Optimise)
+#define DATA_BUFSIZ 10 /** Size to use for DataPoint buffers (TODO: Optimise) **/
 
 
 #include "common.h"
@@ -23,8 +23,8 @@ typedef struct
 /** Enum of output format types for DataPoints **/
 typedef enum
 {
-       JSON, // JSON data
-       TSV // Tab seperated vector
+       JSON, /** JSON data */
+       TSV /** Tab seperated vector */
 } DataFormat;
 
 /** 
@@ -34,10 +34,10 @@ typedef enum
  */
 typedef struct
 {
-       FILE * file; // file pointer
-       int num_points; // Number of DataPoints in the file
-       char * filename; // Name of the file
-       pthread_mutex_t mutex; // Mutex around num_points
+       FILE * file; /** file pointer */
+       int num_points; /** Number of DataPoints in the file */
+       char * filename; /** Name of the file */
+       pthread_mutex_t mutex; /** Mutex around num_points */
 } DataFile;
 
 
@@ -54,7 +54,4 @@ extern double Data_Calibrate(double value, double x[], double y[], int size);
 extern void Data_Handler(DataFile * df, FCGIValue * start, FCGIValue * end, DataFormat format, double current_time); // Helper; given FCGI params print data
 extern DataFormat Data_GetFormat(FCGIValue * fmt); // Helper; convert human readable format string to DataFormat
 
-
-extern double Data_Callibrate(double value, double map[], int map_size);
-
 #endif //_DATAPOINT_H
diff --git a/server/dilatometer.c b/server/dilatometer.c
deleted file mode 100644 (file)
index 83cdc4c..0000000
+++ /dev/null
@@ -1,290 +0,0 @@
-/**
- * @file dilatometer.c
- * @purpose Implementation of dilatometer related functions
- */
-
-#include "cv.h"
-#include "highgui_c.h"
-#include "dilatometer.h"
-#include <math.h>
-
-// test positions
-static double test_left, test_right;
-
-// Canny Edge algorithm variables
-int blur = 5;
-int lowThreshold = 30;
-int ratio = 3;
-int kernel_size = 3;
-
-/** Buffers for storing image data.  **/
-static CvMat * g_srcRGB  = NULL;       // Source Image
-static CvMat * g_srcGray = NULL;       // Gray scale of source image
-static CvMat * g_edges          = NULL;        // Detected Edges
-
-/** Pointers for capturing image **/
-static CvCapture * g_capture = NULL;
-static IplImage * frame  = NULL;       // This is required as you can not use capture with CvMat in C
-
-
-/**
- * Create a test image using left as left edge and right as right edge positions
- */
-void Dilatometer_TestImage()
-{
-       
-       g_srcRGB = cvCreateMat(480, 640, CV_8UC3);
-
-       for( int x = 0; x < 640; ++x)
-       {
-               for (int y = 0; y < 480; ++y)
-               {
-                       CvScalar s; 
-                       for( int i = 0; i < 3; ++i)
-                       {
-                               s.val[i]  =  210 + (rand() % 1000) * 1e-0 - (rand() % 1000) * 1e-0;
-                               // Produce an exponential decay around left edge
-                               if( x < test_left)
-                                       s.val[i] *= exp( (x - test_left) / 25);
-                               else if( x < 320)
-                                       s.val[i] *= exp( (test_left - x) / 25); 
-                               // Produce an exponential decay around right edge
-                               else if( x < test_right)
-                                       s.val[i] *= exp( (x - test_right) / 25); 
-                               else
-                                       s.val[i] *= exp( (test_right - x) / 25);                                
-                       }       
-                       cvSet2D(g_srcRGB,y,x,s);
-               }
-               
-       }
-       if (g_srcGray == NULL)
-       {
-               g_srcGray = cvCreateMat(g_srcRGB->rows,g_srcRGB->cols,CV_8UC1);
-       }
-       cvCvtColor(g_srcRGB,g_srcGray,CV_RGB2GRAY);
-}      
-
-/**
- * Cleanup Dilatometer pointers
- */
-void Dilatometer_Cleanup()
-{
-       if (g_capture != NULL)
-               cvReleaseCapture(&g_capture);
-       if (frame != NULL)
-               cvReleaseImageHeader(&frame);
-       //if (g_srcRGB != NULL)
-       //      cvReleaseMat(&g_srcRGB);        // Causing run time error in cvReleaseMat
-       if (g_srcGray != NULL)
-               cvReleaseMat(&g_srcGray);
-       if (g_edges != NULL)
-               cvReleaseMat(&g_edges);
-}
-
-/**
- * Get an image from the Dilatometer
- */
-static bool Dilatometer_GetImage()
-{      
-       bool result = true;
-       // If more than one camera is connected, then input needs to be determined, however the camera ID may change after being unplugged
-       if( g_capture == NULL)
-       {
-               g_capture = cvCreateCameraCapture(0);
-               //If cvCreateCameraCapture returns NULL there is an error with the camera
-               if( g_capture == NULL)
-               {
-                       result = false;
-                       return;
-               }
-       }
-
-       // Get the frame and convert it to CvMat
-       frame =  cvQueryFrame(g_capture);
-       CvMat stub;
-       g_srcRGB = cvGetMat(frame,&stub,0,0);
-
-       if( g_srcRGB == NULL)
-               result = false;
-       
-       // Convert the image to grayscale
-       if (g_srcGray == NULL)
-       {
-               g_srcGray = cvCreateMat(g_srcRGB->rows,g_srcRGB->cols,CV_8UC1);
-       }
-
-       cvCvtColor(g_srcRGB,g_srcGray,CV_RGB2GRAY);
-       
-       return result;
-}
-
-void CannyThreshold()
-{
-       if ( g_edges == NULL)
-       {
-               g_edges = cvCreateMat(g_srcGray->rows,g_srcGray->cols,CV_8UC1);
-       }
-       
-       // Commented out lines are used during testing to show the image to screen, can also save the test images
-       //cvShowImage("display", g_srcGray);
-       //cvWaitKey(0);         
-       
-       // Reduce noise with a kernel blurxblur. Input the grayscale source image, output to edges. (0's mean it's determined from kernel sizes)
-       cvSmooth( g_srcGray, g_edges, CV_GAUSSIAN, blur, blur ,0 ,0 );
-       
-       //Save the image
-       //cvSaveImage("test_blurred.jpg",g_edges,0);
-
-       //cvShowImage("display", g_edges);
-       //cvWaitKey(0); 
-
-       // Find the edges in the image
-       cvCanny( g_edges, g_edges, lowThreshold, lowThreshold*ratio, kernel_size );
-       
-       //Save the image
-       //cvSaveImage("test_edge.jpg",g_edges,0);
-
-       //cvShowImage("display", g_edges);
-       //cvWaitKey(0);         
-
-}
-
- /**
- * Read the dilatometer image. The value changed will correspond to the new location of the edge.
- * @param val - Will store the read value if successful
- * @param samples - Number of rows to scan (increasing will slow down performance!)
- * @returns true on successful read
- */
-bool Dilatometer_GetEdge( double * value, int samples)
-{
-       bool result = false; 
-       double average = 0;
-       // Get the image from the camera
-       result = Dilatometer_GetImage();
-       // If an error occured when capturing image then return
-       if (!result)
-               return result;
-       
-       // Apply the Canny Edge theorem to the image
-       CannyThreshold();
-
-       int width = g_edges->cols;
-       int height = g_edges->rows;
-       
-       // If the number of samples is greater than the image height, sample every row
-       if( samples > height)
-       {
-               samples = height;
-       }
-       
-       int sample_height;
-       int num_edges = 0;      // Number of edges. if each sample location has an edge, then num_edges = samples
-
-       for (int i=0; i<samples; i++)
-       {
-               // Determine the position in the rows to find the edges. 
-               // This will give you a number of evenly spaced samples
-               sample_height = ceil(height * (i + 1) / samples) -1;
-               
-               // Need to go through each pixel of a row and find all the locations of a line. If there is more than one pixel, average it. note this only works if the canny edge algorithm returns lines about the actual line (no outliers).
-               
-               int edge_location=0;
-               int num=0;
-               for ( int col = 0; col < width; col++)
-               {
-                       // Count the number of points
-                       // Get the threshold of the pixel at the current location
-                       CvScalar value = cvGet2D(g_edges, sample_height, col);
-                       if( value.val[0]> THRES)
-                       {
-                               edge_location += col;
-                               num++;
-                       }
-               }
-               if( num > 0)
-               {
-                       average += ( edge_location / num );
-                       num_edges++;
-               }
-       }
-       if (num_edges > 0)
-               average /= num_edges;
-       
-       if( average > 0)
-       {       
-               result = true; //Successfully found an edge
-               *value = average;
-       }
-       return result;
-}
-
- /**
- * Read the dilatometer image. The value changed will correspond to the new location of the edge.
- * @param val - Will store the read value if successful
- * @returns true on successful read
- */
-bool Dilatometer_Read( double * value)
-{
-       bool result = Dilatometer_GetEdge(value, SAMPLES);
-       return result;
-}
-
-/**
- * Initialise the dilatometer
- */
-void Dilatometer_Init()
-{
-       // Make an initial reading (will allocate memory the first time only).
-       double val;
-       Dilatometer_GetEdge(&val, 1); 
-}
-
-// Overlays a line over the given edge position
-void Draw_Edge(double edge)
-{
-       CvScalar value;
-       value.val[0]=244;
-       for( int i = 0; i < g_srcGray->rows; i++)
-       {
-               cvSet2D(g_edges,i,edge,value);
-       }
-       cvShowImage("display", g_edges);
-       cvWaitKey(0);   
-       //cvSaveImage("test_edge_avg.jpg",g_edges,0);
-}
-
-/* // Test algorithm
-static void Dilatometer_GetImageTest( )
-{      
-       //Generates Test image
-       //Dilatometer_TestImage();
-       
-       //Load Test image
-       g_srcGray = cvLoadImageM ("testimage4.jpg",CV_LOAD_IMAGE_GRAYSCALE );
-}*/
-
-/**
- * For testing purposes
- */
-int main(int argc, char ** argv)
-{
-       //cvNamedWindow( "display", CV_WINDOW_AUTOSIZE );// Create a window for display.
-       //gettimeofday(&start, NULL);
-       test_left = 100;
-       test_right = 500;
-       Dilatometer_Init();
-       
-       cvNamedWindow( "display", CV_WINDOW_AUTOSIZE);
-       //double width;
-       
-       double edge;
-       Dilatometer_GetEdge(&edge,20000);
-       //For testing purposes, overlay the given average line over the image
-       //Draw_Edge(edge);
-       
-       cvDestroyWindow("display");
-
-       Dilatometer_Cleanup();
-}
-
diff --git a/server/dilatometer.h b/server/dilatometer.h
deleted file mode 100644 (file)
index 7bb9447..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/**
- * @file dilatometer.h
- * @brief Declarations for functions to deal with dilatometer
- */
-
-#include "common.h"
-
-//Threshold to determine the edge of the can
-#define THRES 230
-
-//Number of samples of the image to take
-#define SAMPLES 600
-
-extern void Dilatometer_Init(); // Initialise the dilatometer
-extern void Dilatometer_Cleanup(); // Cleanup
-extern bool Dilatometer_Read( double * value); // Read the Dilatometer
-
index 9ff3acc..6006322 100644 (file)
@@ -164,7 +164,6 @@ bool FCGI_LockControl(FCGIContext *context, const char * user_name, UserType use
  * the key) has control or not. If validated, the context control_timestamp is
  * updated.
  * @param context The context to work in
- * @param key The control key to be validated.
  * @return TRUE if authorized, FALSE if not.
  */
 bool FCGI_HasControl(FCGIContext *context)
@@ -386,7 +385,6 @@ void FCGI_BeginJSON(FCGIContext *context, StatusCodes status_code)
  * Generic accept response in JSON format.
  * @param context The context to work in
  * @param description A short description.
- * @param cookie Optional. If given, the cookie field is set to that value.
  */
 void FCGI_AcceptJSON(FCGIContext *context, const char *description)
 {
@@ -510,7 +508,7 @@ void FCGI_WriteBinary(void * data, size_t size, size_t num_elem)
 /**
  * Escapes a string so it can be used safely.
  * Currently escapes to ensure the validity for use as a JSON string
- * Does not support unicode specifiers in the form of \uXXXX.
+ * Does not support unicode specifiers in the form of \\uXXXX.
  * @param buf The string to be escaped
  * @return The escaped string (return value == buf)
  */
index a417a43..09884d1 100644 (file)
@@ -35,12 +35,20 @@ typedef enum StatusCodes {
 
 #define CONTROL_KEY_BUFSIZ 41
 
+/**
+ * An entry that describes an expected user parameter for parsing.
+ * To be used in conjunction with @see FCGI_ParseRequest.
+ */
 typedef struct FCGIValue {
+       /** The name of the key (from key/value pair) [in] **/
        const char *key;
+       /** A pointer to a variable that will hold the parsed value [out] **/
        void *value;
+       /** Bit flags that determine things like if the field is required and if it was received [in/out] **/
        unsigned flags;
 } FCGIValue;
 
+/** The type of a user (unauthorised, normal, admin). **/
 typedef enum {USER_UNAUTH, USER_NORMAL, USER_ADMIN} UserType;
 
 /**Contextual information related to FCGI requests*/
@@ -66,6 +74,7 @@ typedef struct
        int response_number;
 } FCGIContext;
 
+/** The type definition of a module handler. **/
 typedef void (*ModuleHandler) (FCGIContext *context, char *params);
 
 extern bool FCGI_LockControl(FCGIContext *context, const char * user_name, UserType user_type);
index dcc122d..0e4ff48 100644 (file)
@@ -8,6 +8,11 @@
 static CvCapture * g_capture = NULL;
 static int g_captureID = -1;
 
+/**
+ * Image stream handler. Returns an image to the user.
+ * @param context The context to work in
+ * @param params User specified parameters
+ */
 void Image_Handler(FCGIContext * context, char * params)
 {
 
@@ -53,7 +58,7 @@ void Image_Handler(FCGIContext * context, char * params)
  * @param num - Camera id
  * @param width - Width to force
  * @param height - Height to force
- * @param image - Pointer to CvMat* to set with result
+ * @param frame - Pointer to IplImage* to set with result
  * @returns true on success, false on error 
  */
  bool Camera_GetImage(int num, int width, int height,  IplImage ** frame)
@@ -97,6 +102,9 @@ void Image_Handler(FCGIContext * context, char * params)
        return result;
 }
 
+/**
+ * Executed on cleanup. Releases the OpenCV Capture structs.
+ */
 void Image_Cleanup()
 {
        // Release the capture and IplImage pointers
index 8e2cd68..9074e85 100644 (file)
@@ -9,7 +9,7 @@
 #include "common.h"
 #include "cv.h"
 
-extern void Image_Init();
+//extern void Image_Init();
 extern void Image_Handler(FCGIContext * context, char * params); 
 extern void Image_Cleanup();
 extern bool Camera_GetImage(int num, int width, int height,  IplImage ** image);
diff --git a/server/interferometer.c b/server/interferometer.c
deleted file mode 100644 (file)
index 4861318..0000000
+++ /dev/null
@@ -1,288 +0,0 @@
-/**
- * @file interferometer.c
- * @purpose Implementation of interferometer related functions
- */
-
-#include "cv.h"
-#include "highgui_c.h"
-#include "interferometer.h"
-#include <math.h>
-
-/** Buffer for storing image data. Stored as a single intensity value for the laser light **/
-static CvMat * g_data = NULL;
-
-
-/** Camera capture pointer **/
-static CvCapture * g_capture = NULL;
-
-
-struct timeval start;
-
-#define PI 3.141592
-
-// For testing purposes
-double test_omega = 0.05;
-double test_angle = PI/2;
-double test_noise[] = {0,0,0.02};
-double test_phase = 0;
-double test_intensity = 1.0;
-
-
-static void Interferometer_TestSinusoid()
-{
-       if (g_capture == NULL)
-       {
-               g_capture = cvCreateCameraCapture(0);
-       }
-
-       // Get image from camera
-       IplImage * img = cvQueryFrame(g_capture);
-
-       // Convert to CvMat
-       CvMat stub;
-       CvMat * background = cvGetMat(img, &stub, 0, 0);
-       // ... Honestly, I have no idea what the "stub" is for
-
-       if (g_data == NULL)
-       {
-               g_data = cvCreateMat(background->rows, background->cols, CV_32FC3);
-       }
-
-       //cvShowImage("background", background);
-
-       for (int x = 0; x < g_data->cols-1; ++x)
-       {
-               for (int y = 0; y < g_data->rows-1; ++y)
-               {
-                       // Calculate pure sine in test direction
-                       double r = x*cos(test_angle) + y*sin(test_angle);
-                       double value = 0.5*test_intensity*(1+sin(test_omega*r + test_phase));
-
-                       CvScalar s; 
-                       s.val[0] = 0; s.val[1] = 0; s.val[2] = value;
-                       CvScalar b = cvGet2D(background, y, x);
-
-
-                       // Add noise & background image
-
-                       // Get the order the right way round
-                       double t = b.val[0];
-                       b.val[0] = b.val[2];
-                       b.val[2] = t;
-                       for (int i = 0; i < 3; ++i)
-                       {
-                                       
-                               s.val[i] += (rand() % 1000) * 1e-3 * test_noise[i];
-                               s.val[i] += b.val[i] / 255; // Camera image is 0-255
-                       }
-
-                       //printf("set %d,%d\n", x, y);
-
-               
-
-                       cvSet2D(g_data,y, x, s);
-               }
-       }       
-
-
-}
-
-
-/**
- * Get an image from the Interferometer
- */
-static void Interferometer_GetImage()
-{
-
-
-       Interferometer_TestSinusoid();
-       //TODO: Implement camera 
-
-}
-
-/**
- * Initialise the Interferometer
- */
-void Interferometer_Init()
-{
-       
-       // Make an initial reading (will allocate memory the first time only).
-       Interferometer_Read(1); 
-}
-
-/**
- * Cleanup Interferometer stuff
- */
-void Interferometer_Cleanup()
-{
-       if (g_data != NULL)
-               cvReleaseMat(&g_data);
-
-       if (g_capture != NULL)
-               cvReleaseCapture(&g_capture);
-
-}
-
-/**
- * Read the interferometer; gets the latest image, processes it, spits out a single number
- * @param samples - Number of columns to scan (increasing will slow down performance!)
- * @returns Value proportional to the change in interferometer path length since the last call to this function
- */
-double Interferometer_Read(int samples)
-{
-
-
-
-
-       // Get the latest image
-       Interferometer_GetImage();
-       // Frequency of the sinusoid
-       static double omega = 0;
-       // Stores locations of nodes
-       static int nodes[MAXNODES];
-       // Current phase
-       static double phase = 0;
-
-       // Phase
-       double cur_phase = 0;
-
-       int xstep = g_data->cols / (samples+1);
-
-       // Used for testing to see where the nodes are identified
-       // (Can't modify g_data)
-       static CvMat * test_overlay = NULL;
-       if (test_overlay == NULL)
-       {
-               // Creates a memory leak; don't do this in the final version!
-               test_overlay = cvCreateMat(g_data->rows, g_data->cols, CV_32FC3);
-       }
-       cvZero(test_overlay);
-       //cvCopy(g_data, test_overlay, NULL);
-
-       // For each column to sample
-       for (int x = xstep; x < g_data->cols; x += xstep)
-       {
-               
-               double avg = 0.5; //TODO: Calculate from image
-               double threshold_dif = 0; //TODO: Pick this value
-
-               int num_nodes = 0;
-               
-               // Find nodes
-               for (int y = 1; y < g_data->rows-2 && num_nodes < MAXNODES; ++y)
-               {
-                       if (num_nodes == 0 || abs(nodes[num_nodes-1] - y) > 1)
-                       {
-                               // A "node" is defined where the ajacent points are on opposite sides of the avg
-                               double ldif = INTENSITY(cvGet2D(g_data, y-1,x)) - avg;
-                               double rdif = INTENSITY(cvGet2D(g_data, y+1,x)) - avg;
-
-                               // If that is the case, the product of the differences will be negative
-                               if (ldif * rdif < -threshold_dif)
-                               {
-
-                                       nodes[num_nodes++] = y;
-
-                                       // Put a white line on the overlay to indicate the node was found
-                                       for (int xx = 0; xx < g_data->cols; ++xx)
-                                       {
-                                               CvScalar s; // = cvGet2D(g_data, y, xx);
-                                               s.val[0] = 1; s.val[1] = 1; s.val[2] = 1;
-                                               cvSet2D(test_overlay, y, xx, s);
-                                       }
-                               }
-                       }
-               }
-
-               // Insufficient nodes found to continue
-               if (num_nodes < 2)
-               {
-                       --samples;
-                       continue;
-               }
-
-               // Estimate angular frequency from two nodes TODO: Average between nodes
-               double slice_omega = (PI*(num_nodes-1)) / (nodes[num_nodes-1] - nodes[0]);
-               //printf("SLICE: %f vs %f\n", slice_omega, test_omega);
-
-               double slice_phase = 0;
-               for (int i = 0; i < num_nodes; ++i)
-               {
-                       double this_phase = ((double)(i)*PI - slice_omega * nodes[i]);
-                       //printf("Node %d gives phase %f\n", i, this_phase);
-                       slice_phase += this_phase;
-               }
-               slice_phase /= num_nodes;
-               cur_phase += slice_phase;
-       }
-
-       // Average over samples
-       if (samples == 0)
-               return 0;
-
-       cur_phase /= samples;
-
-
-
-       // Get phase change since last call, save current phase
-       double result = (cur_phase - phase);
-
-       // HACK
-       if (abs(result) > 0.5*PI)
-       {
-               if (result > 0)
-                       result -= PI;
-               else
-                       result += PI;
-       }       
-       phase = cur_phase;
-
-       // Display the image with lines to indicate results of data processing
-       //cvShowImage("nodes", test_overlay);
-       //cvWaitKey(1);
-       cvAdd(test_overlay, g_data, test_overlay, NULL);
-       cvShowImage("overlay", test_overlay);
-       cvWaitKey(1);
-       return result;
-
-}
-
-/**
- * For testing purposes
- */
-int main(int argc, char ** argv)
-{
-       //cvNamedWindow( "display", CV_WINDOW_AUTOSIZE );// Create a window for display.
-       gettimeofday(&start, NULL);
-
-       //Interferometer_Read(1);
-       //exit(EXIT_SUCCESS);
-
-       Interferometer_Init();
-
-       double sum = 0;
-       double last_phase = test_phase;
-
-       struct timeval now;
-       double time = 0;
-
-       while (time < 20)
-       {
-               gettimeofday(&now, NULL);
-               time = TIMEVAL_DIFF(now, start);
-               
-               test_phase = 0.5*PI*sin(time);
-
-               
-               double delta = Interferometer_Read(1);
-               sum += delta;
-       
-               printf("%f\t%f\t%f\t%f\t%f\n", time, test_phase - last_phase, test_phase, delta, sum);  
-
-               last_phase = test_phase;
-               //break;
-       }
-       
-}
-
-
diff --git a/server/interferometer.h b/server/interferometer.h
deleted file mode 100644 (file)
index f545463..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-/**
- * @file interferometer.h
- * @purpose Declarations for functions to deal with interferometer
- */
-
-#include "common.h"
-
-//#define INTENSITY(rgb) ((rgb).val[0]*(rgb).val[0] + (rgb).val[1]*(rgb).val[1] + (rgb).val[2]*(rgb).val[2])
-#define INTENSITY(rgb) ((rgb).val[2])
-
-#define MAXNODES 100 //TODO: Choose value based on real data
-
-extern void Interferometer_Init(); // Initialise the interferometer
-extern void Interferometer_Cleanup(); // Cleanup
-extern double Interferometer_Read(); // Read the interferometer
-
-
-
diff --git a/server/intertest.sh b/server/intertest.sh
deleted file mode 100755 (executable)
index f3012ad..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-rm intertest
-make intertest
-./intertest > test.dat
-
-cmd="set title \"Interferometer Test\""
-cmd="$cmd; set xlabel \"Time (s)\""
-cmd="$cmd; set ylabel \"Phase (rad)\""
-cmd="$cmd; plot \"test.dat\" u 1:3 t \"Specified\" w l, \"test.dat\" u 1:5 t \"Calculated\" w p"
-gnuplot --persist -e "$cmd"
-
-cmd="set title \"Interferometer Test\""
-cmd="$cmd; set xlabel \"Time (s)\""
-cmd="$cmd; set ylabel \"Delta Phase (rad)\""
-cmd="$cmd; plot \"test.dat\" u 1:2 t \"Specified\" w l, \"test.dat\" u 1:4 t \"Measured\" w p"
-gnuplot --persist -e "$cmd"
diff --git a/server/microscope.c b/server/microscope.c
deleted file mode 100644 (file)
index e388073..0000000
+++ /dev/null
@@ -1,246 +0,0 @@
-/**
- * @file microscope.c
- * @purpose Implementation of microscope related functions
- */
-
-#include "cv.h"
-#include "highgui_c.h"
-#include "microscope.h"
-#include <math.h>
-
-// test positions
-static double test_left, test_right;
-
-// Canny Edge algorithm variables
-int lowThreshold = 30;
-int ratio = 3;
-int kernel_size = 3;
-
-/** Buffer for storing image data. Stored as a  **/
-static CvMat * g_srcRGB  = NULL; // Source Image
-static CvMat * g_srcGray = NULL; // Gray scale of source image
-static CvMat * g_edges          = NULL; // Detected Edges
-static CvMat * g_data    = NULL; // Image to mask edges onto
-
-
-/** Camera capture pointer **/
-static CvCapture * g_capture = NULL;
-
-/**
- * Create a test image using left as left edge and right as right edge positions
- */
-void Dilatometer_TestImage()
-{
-       
-       g_srcRGB = cvCreateMat(480, 640, CV_8UC3);
-
-       for( int x = 0; x < 640; ++x)
-       {
-               for (int y = 0; y < 480; ++y)
-               {
-                       CvScalar s; 
-                       for( int i = 0; i < 3; ++i)
-                       {
-                               s.val[i]  =  210 + (rand() % 1000) * 1e-0 - (rand() % 1000) * 1e-0;
-                               // Produce an exponential decay around left edge
-                               if( x < test_left)
-                                       s.val[i] *= exp( (x - test_left) / 25);
-                               else if( x < 320)
-                                       s.val[i] *= exp( (test_left - x) / 25); 
-                               // Produce an exponential decay around right edge
-                               else if( x < test_right)
-                                       s.val[i] *= exp( (x - test_right) / 25); 
-                               else
-                                       s.val[i] *= exp( (test_right - x) / 25);                                
-                       }       
-                       cvSet2D(g_srcRGB,y,x,s);
-               //      if( s.val[0] > 200)
-               //              printf("row: %d, col: %d, %f\n", y, x, s.val[0]); 
-               }
-               
-       }
-       if (g_data == NULL)
-       {
-               g_data = cvCreateMat(g_srcRGB->rows,g_srcRGB->cols,CV_8UC1); //IPL_DEPTH_8U?
-       }
-       cvCvtColor(g_srcRGB,g_data,CV_RGB2GRAY);
-}      
-
-/**
- * Initialise the dilatometer
- */
-void Microscope_Init()
-{
-       
-       // Make an initial reading (will allocate memory the first time only).
-       double val;
-       Microscope_Read(&val, 1); 
-}
-
-/**
- * Cleanup Interferometer stuff
- */
-void Microscope_Cleanup()
-{
-       if (g_data != NULL)
-               cvReleaseMat(&g_data);
-
-       if (g_capture != NULL)
-               cvReleaseCapture(&g_capture);
-
-}
-
-/**
- * Get an image from the Dilatometer
- */
-static void Microscope_GetImage()
-{      
-       //Need to implement camera
-}
-
-void CannyThreshold()
-{
-       
-       if (g_data == NULL)
-       {
-               g_data = cvCreateMat(g_srcGray->rows,g_srcGray->cols,CV_8UC1);
-       }
-
-       if ( g_edges == NULL)
-       {
-               g_edges = cvCreateMat(g_srcGray->rows,g_srcGray->cols,CV_8UC1);
-       }
-       
-       //g_data = 0;
-       cvShowImage("display", g_srcGray);
-       cvWaitKey(0);   
-       // Reduce noise with a kernel 3x3. Input the grayscale source image, output to edges. (0's mean it's determined from kernel sizes)
-       cvSmooth( g_srcGray, g_edges, CV_GAUSSIAN, 9, 9 ,0 ,0 );
-       
-       cvShowImage("display", g_edges);
-       cvWaitKey(0);   
-       
-       // Find the edges in the image
-       lowThreshold = 35;
-       cvCanny( g_edges, g_edges, lowThreshold, lowThreshold*ratio, kernel_size );
-
-       cvShowImage("display", g_edges);
-       cvWaitKey(0);   
-       
-       // Mask the edges over G_data
-       //.copyTo( g_data, g_edges);
-}
-
-// Test algorithm
-static void Microscope_GetImageTest( )
-{      
-       //Generates Test image
-       //Dilatometer_TestImage();
-       
-       //Load Test image
-       g_srcGray = cvLoadImageM ("testimage.jpg",CV_LOAD_IMAGE_GRAYSCALE );
-       CannyThreshold();
-}
-
-
- /**
- * Read the microscope image. The value changed will correspond to the new location of the edge.
- * @param val - Will store the read value if successful
- * @param samples - Number of rows to scan (increasing will slow down performance!)
- * @returns true on successful read
- */
-bool Microscope_Read( double * value, int samples)
-{
-       bool result = false; 
-       double average = 0;
-       // Get the image from the camera
-       Microscope_GetImageTest();
-       
-       int width = g_edges->cols;
-       int height = g_edges->rows;
-       
-       // If the number of samples is greater than the image height, sample every row
-       if( samples > height)
-       {
-               samples = height;
-       }
-       
-       int sample_height;
-       int num_edges = 0;      // Number of edges. if each sample location has an edge, then num_edges = samples
-
-       for (int i=0; i<samples; i++)
-       {
-               // Determine the position in the rows to find the edges. 
-               // This will give you a number of evenly spaced samples
-               sample_height = ceil(height * (i + 1) / samples) -1;
-               
-               // Need to go through each pixel of a row and find all the locations of a line. If there is more than one pixel, average it. note this only works if the canny edge algorithm returns lines about the actual line (no outliers).
-               
-               int edge_location=0;
-               int num=0;
-               for ( int col = 0; col < width; col++)
-               {
-                       // Count the number of points
-                       // Get the threshold of the pixel at the current location
-                       CvScalar value = cvGet2D(g_edges, sample_height, col);
-                       //printf("row: %d, col: %d, value: %f\n",sample_height, col, value.val[0]);
-                       if( value.val[0]> THRES)
-                       {
-                               edge_location += col;
-                               num++;
-                       }
-               }
-               if( num > 0)
-               {
-                       average += ( edge_location / num );
-                       num_edges++;
-                       printf("average %f\n", average/num_edges);
-               }
-       }
-       if (num_edges > 0)
-               average /= num_edges;
-       
-       if( average > 0)
-       {       
-               result = true; //Successfully found an edge
-               *value = average;
-       }
-       return result;
-}
-
-// Overlays a line over the given edge position
-void Draw_Edge(double edge)
-{
-       CvScalar value;
-       value.val[0]=244;
-       for( int i = 0; i < g_srcGray->rows; i++)
-       {
-               cvSet2D(g_edges,i,edge,value);
-       }
-       cvShowImage("display", g_edges);
-       cvWaitKey(0);   
-}
-
-/**
- * For testing purposes
- */
-int main(int argc, char ** argv)
-{
-       //cvNamedWindow( "display", CV_WINDOW_AUTOSIZE );// Create a window for display.
-       //gettimeofday(&start, NULL);
-       test_left = 100;
-       test_right = 500;
-       Microscope_Init();
-       
-       cvNamedWindow( "display", CV_WINDOW_AUTOSIZE);
-//     cvShowImage("display", g_data);
-//     cvWaitKey(0);   
-       double width;
-       
-       double edge;
-       Microscope_Read(&edge,15);
-       //For testing purposes, overlay the given average line over the image
-       Draw_Edge(edge);
-
-}
-
diff --git a/server/microscope.h b/server/microscope.h
deleted file mode 100644 (file)
index ca63b5e..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-/**
- * @file microscope.h
- * @brief Declarations for functions to deal with microscope
- */
-
-#include "common.h"
-
-//Threshold to determine the edge of the can
-#define THRES 230
-
-extern void Microscope_Init(); // Initialise the dilatometer
-extern void Microscope_Cleanup(); // Cleanup
-extern bool Microscope_Read( double * value, int samples); // Read the Microscope
-
index 77c0ef9..8640a60 100644 (file)
@@ -30,6 +30,12 @@ void Pin_Close()
                PWM_Unexport(i);
 }
 
+/**
+ * Configures a pin (Export/Unexport business)
+ * @param type The pin type (GPIO/PWM/ADC)
+ * @param pin_export Whether to export/unexport/leave-as-is the pin
+ * @param num The pin number
+ */
 bool Pin_Configure(const char *type, int pin_export, int num)
 {
        bool ret = true;
index 4e8ac7f..3919a19 100644 (file)
@@ -23,10 +23,8 @@ int g_num_sensors = 0;
  * @param user_id - User identifier
  * @param read - Function to call whenever the sensor should be read
  * @param init - Function to call to initialise the sensor (may be NULL)
- * @param max_error - Maximum error threshold; program will exit if this is exceeded for the sensor reading
- * @param min_error - Minimum error threshold; program will exit if the sensor reading falls below this value
- * @param max_warn - Maximum warning threshold; program will log warnings if the value exceeds this threshold
- * @param min_warn - Minimum warning threshold; program will log warnings if the value falls below this threshold
+ * @param cleanup - Function to call whenever to deinitialise the sensor (may be NULL)
+ * @param sanity - Function to call to check that the sensor value is sane (may be NULL)
  * @returns Number of actuators added so far
  */
 int Sensor_Add(const char * name, int user_id, ReadFn read, InitFn init, CleanFn cleanup, SanityFn sanity)
@@ -277,7 +275,7 @@ Sensor * Sensor_Identify(const char * name)
 /**
  * Helper: Begin sensor response in a given format
  * @param context - the FCGIContext
- * @param id - ID of sensor
+ * @param s - Sensor to begin the response for
  * @param format - Format
  */
 void Sensor_BeginResponse(FCGIContext * context, Sensor * s, DataFormat format)
@@ -300,7 +298,7 @@ void Sensor_BeginResponse(FCGIContext * context, Sensor * s, DataFormat format)
 /**
  * Helper: End sensor response in a given format
  * @param context - the FCGIContext
- * @param id - ID of the sensor
+ * @param s - Sensor to end the response for
  * @param format - Format
  */
 void Sensor_EndResponse(FCGIContext * context, Sensor * s, DataFormat format)
@@ -424,6 +422,11 @@ const char * Sensor_GetName(int id)
        return g_sensors[id].name;
 }
 
+/**
+ * Returns the last DataPoint that is currently available.
+ * @param id - The sensor ID for which to retrieve data from
+ * @return The last DataPoint
+ */
 DataPoint Sensor_LastData(int id)
 {
        Sensor * s = &(g_sensors[id]);
index 3de48e0..b2bb63c 100644 (file)
@@ -80,7 +80,7 @@ extern void Sensor_SetModeAll(ControlModes mode, void * arg);
 extern void Sensor_SetMode(Sensor * s, ControlModes mode, void * arg);
 
 extern void * Sensor_Loop(void * args); // Main loop for a thread that handles a Sensor
-extern bool Sensor_Read(Sensor * s, DataPoint * d); // Read a single DataPoint, indicating if it has changed since the last one
+//extern bool Sensor_Read(Sensor * s, DataPoint * d); // Read a single DataPoint, indicating if it has changed since the last one
 extern Sensor * Sensor_Identify(const char * str); // Identify a Sensor from a string
 
 extern void Sensor_Handler(FCGIContext *context, char * params); // Handle a FCGI request for Sensor data
diff --git a/server/stream.c b/server/stream.c
deleted file mode 100644 (file)
index e1e23c1..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-#include "cv.h"
-#include "highgui_c.h"
-#include <string.h>
-#include <stdio.h>
-
-/*-------------------------------------------------------------------
-
-compile with:
--I/usr/include/opencv -I/usr/include/opencv2/highgui -L/usr/lib -lopencv_highgui -lopencv_core -lopencv_ml -lopencv_imgproc
-
---------------------------------------------------------------------*/
-
-int storeFrame( CvCapture* capture)
-{
-       IplImage *frame;
-       CvMat* jpg;
-       
-       //FILE *fp = fopen ("test.jpg", "wb");
-
-       int p[3];
-       p[0] = CV_IMWRITE_JPEG_QUALITY;
-       p[1] = 100;     //quality value. 0-100
-       p[2] = 0;
-               
-       frame = cvQueryFrame(capture);
-       if( frame == NULL)
-               return 0;       //error
-       cvSaveImage("../web/images/test.JPG",frame,p);
-       //jpg = cvEncodeImage(".jpg", frame,p); 
-       /*pass buf to client, write to file on client*/
-       //fwrite(jpg->data.ptr,1,jpg->rows*jpg->cols, fp);
-       
-       //decjpg = cvDecodeImage(jpg, CV_LOAD_IMAGE_COLOR);
-       //cvShowImage( "Display window", decjpg );  
-                       
-       //cvWaitKey(0);
-       cvReleaseImageHeader(&frame);
-       //cvReleaseMat(&jpg);
-       //fclose( fp);
-       return 1;
-}
-
-int main (int argc, char** argv)
-{
-       CvCapture* capture;
-       //cvNamedWindow( "Display window", CV_WINDOW_AUTOSIZE );// Create a window for display.
-       //Get capture structure for camera, -1 refers to any camera device.
-       //If multiple cameras used, need to use specific camera ID
-       capture = cvCreateCameraCapture(-1);
-       //If cvCreateCameraCapture returns NULL there is an error with the camera
-       if( capture == NULL)
-               return -1;
-
-       cvSetCaptureProperty (capture, CV_CAP_PROP_FOURCC, 'MJPEG');
-
-       while(1)
-       {
-               if( !storeFrame( capture))
-                       return -1;
-               printf("enter to continue");
-               getchar();
-               //sleep(1);     //for now just to make the camera take 1 shot a second, as that's all my camera seems to be able to take/save (camera or function causing this? is 1 second per frame enough?)
-       }
-       
-       //Need to determine how the function is called in respect to system. just leave it running with a while loop? will something turn it on and off? will the function be called once from elsewhere?
-       cvReleaseCapture( &capture);
-}
-
diff --git a/testing/Camera/dilatometer/Readme.md b/testing/Camera/dilatometer/Readme.md
new file mode 100644 (file)
index 0000000..231dd69
--- /dev/null
@@ -0,0 +1 @@
+The files here are the previous versions of camera/dilatometer/microscope code that once resided in the main `server` folder. They are now placed here because they are no longer in use.
diff --git a/testing/Camera/dilatometer/dilatometer.c b/testing/Camera/dilatometer/dilatometer.c
new file mode 100644 (file)
index 0000000..7a85878
--- /dev/null
@@ -0,0 +1,295 @@
+/**
+ * @file dilatometer.c
+ * @purpose Implementation of dilatometer related functions
+ */
+
+#include "cv.h"
+#include "highgui_c.h"
+#include "dilatometer.h"
+#include <math.h>
+
+// test positions
+static double test_left, test_right;
+
+// Canny Edge algorithm variables
+int blur = 5;
+int lowThreshold = 30;
+int ratio = 3;
+int kernel_size = 3;
+
+/** Buffers for storing image data.  **/
+static CvMat * g_srcRGB  = NULL;       // Source Image
+static CvMat * g_srcGray = NULL;       // Gray scale of source image
+static CvMat * g_edges          = NULL;        // Detected Edges
+
+/** Pointers for capturing image **/
+static CvCapture * g_capture = NULL;
+static IplImage * frame  = NULL;       // This is required as you can not use capture with CvMat in C
+
+
+/**
+ * Create a test image using left as left edge and right as right edge positions
+ */
+void Dilatometer_TestImage()
+{
+       
+       g_srcRGB = cvCreateMat(480, 640, CV_8UC3);
+
+       for( int x = 0; x < 640; ++x)
+       {
+               for (int y = 0; y < 480; ++y)
+               {
+                       CvScalar s; 
+                       for( int i = 0; i < 3; ++i)
+                       {
+                               s.val[i]  =  210 + (rand() % 1000) * 1e-0 - (rand() % 1000) * 1e-0;
+                               // Produce an exponential decay around left edge
+                               if( x < test_left)
+                                       s.val[i] *= exp( (x - test_left) / 25);
+                               else if( x < 320)
+                                       s.val[i] *= exp( (test_left - x) / 25); 
+                               // Produce an exponential decay around right edge
+                               else if( x < test_right)
+                                       s.val[i] *= exp( (x - test_right) / 25); 
+                               else
+                                       s.val[i] *= exp( (test_right - x) / 25);                                
+                       }       
+                       cvSet2D(g_srcRGB,y,x,s);
+               }
+               
+       }
+       if (g_srcGray == NULL)
+       {
+               g_srcGray = cvCreateMat(g_srcRGB->rows,g_srcRGB->cols,CV_8UC1);
+       }
+       cvCvtColor(g_srcRGB,g_srcGray,CV_RGB2GRAY);
+}      
+
+/**
+ * Cleanup Dilatometer pointers
+ */
+void Dilatometer_Cleanup()
+{
+       if (g_capture != NULL)
+               cvReleaseCapture(&g_capture);
+       if (frame != NULL)
+               cvReleaseImageHeader(&frame);
+       //if (g_srcRGB != NULL)
+       //      cvReleaseMat(&g_srcRGB);        // Causing run time error in cvReleaseMat
+       if (g_srcGray != NULL)
+               cvReleaseMat(&g_srcGray);
+       if (g_edges != NULL)
+               cvReleaseMat(&g_edges);
+}
+
+/**
+ * Get an image from the Dilatometer
+ */
+static bool Dilatometer_GetImage()
+{      
+       bool result = true;
+       // If more than one camera is connected, then input needs to be determined, however the camera ID may change after being unplugged
+       if( g_capture == NULL)
+       {
+               g_capture = cvCreateCameraCapture(0);
+               //If cvCreateCameraCapture returns NULL there is an error with the camera
+               if( g_capture == NULL)
+               {
+                       result = false;
+                       return;
+               }
+       }
+
+       // Get the frame and convert it to CvMat
+       frame =  cvQueryFrame(g_capture);
+       CvMat stub;
+       g_srcRGB = cvGetMat(frame,&stub,0,0);
+
+       if( g_srcRGB == NULL)
+               result = false;
+       
+       // Convert the image to grayscale
+       if (g_srcGray == NULL)
+       {
+               g_srcGray = cvCreateMat(g_srcRGB->rows,g_srcRGB->cols,CV_8UC1);
+       }
+
+       cvCvtColor(g_srcRGB,g_srcGray,CV_RGB2GRAY);
+       
+       return result;
+}
+
+/**
+ * Applies the Canny threshold algorithm to the captured image.
+ */
+void CannyThreshold()
+{
+       if ( g_edges == NULL)
+       {
+               g_edges = cvCreateMat(g_srcGray->rows,g_srcGray->cols,CV_8UC1);
+       }
+       
+       // Commented out lines are used during testing to show the image to screen, can also save the test images
+       //cvShowImage("display", g_srcGray);
+       //cvWaitKey(0);         
+       
+       // Reduce noise with a kernel blurxblur. Input the grayscale source image, output to edges. (0's mean it's determined from kernel sizes)
+       cvSmooth( g_srcGray, g_edges, CV_GAUSSIAN, blur, blur ,0 ,0 );
+       
+       //Save the image
+       //cvSaveImage("test_blurred.jpg",g_edges,0);
+
+       //cvShowImage("display", g_edges);
+       //cvWaitKey(0); 
+
+       // Find the edges in the image
+       cvCanny( g_edges, g_edges, lowThreshold, lowThreshold*ratio, kernel_size );
+       
+       //Save the image
+       //cvSaveImage("test_edge.jpg",g_edges,0);
+
+       //cvShowImage("display", g_edges);
+       //cvWaitKey(0);         
+
+}
+
+ /**
+ * Read the dilatometer image. The value changed will correspond to the new location of the edge.
+ * @param val - Will store the read value if successful
+ * @param samples - Number of rows to scan (increasing will slow down performance!)
+ * @returns true on successful read
+ */
+bool Dilatometer_GetEdge( double * value, int samples)
+{
+       bool result = false; 
+       double average = 0;
+       // Get the image from the camera
+       result = Dilatometer_GetImage();
+       // If an error occured when capturing image then return
+       if (!result)
+               return result;
+       
+       // Apply the Canny Edge theorem to the image
+       CannyThreshold();
+
+       int width = g_edges->cols;
+       int height = g_edges->rows;
+       
+       // If the number of samples is greater than the image height, sample every row
+       if( samples > height)
+       {
+               samples = height;
+       }
+       
+       int sample_height;
+       int num_edges = 0;      // Number of edges. if each sample location has an edge, then num_edges = samples
+
+       for (int i=0; i<samples; i++)
+       {
+               // Determine the position in the rows to find the edges. 
+               // This will give you a number of evenly spaced samples
+               sample_height = ceil(height * (i + 1) / samples) -1;
+               
+               // Need to go through each pixel of a row and find all the locations of a line. If there is more than one pixel, average it. note this only works if the canny edge algorithm returns lines about the actual line (no outliers).
+               
+               int edge_location=0;
+               int num=0;
+               for ( int col = 0; col < width; col++)
+               {
+                       // Count the number of points
+                       // Get the threshold of the pixel at the current location
+                       CvScalar value = cvGet2D(g_edges, sample_height, col);
+                       if( value.val[0]> THRES)
+                       {
+                               edge_location += col;
+                               num++;
+                       }
+               }
+               if( num > 0)
+               {
+                       average += ( edge_location / num );
+                       num_edges++;
+               }
+       }
+       if (num_edges > 0)
+               average /= num_edges;
+       
+       if( average > 0)
+       {       
+               result = true; //Successfully found an edge
+               *value = average;
+       }
+       return result;
+}
+
+ /**
+ * Read the dilatometer image. The value changed will correspond to the new location of the edge.
+ * @param val - Will store the read value if successful
+ * @returns true on successful read
+ */
+bool Dilatometer_Read( double * value)
+{
+       bool result = Dilatometer_GetEdge(value, SAMPLES);
+       return result;
+}
+
+/**
+ * Initialise the dilatometer
+ */
+void Dilatometer_Init()
+{
+       // Make an initial reading (will allocate memory the first time only).
+       double val;
+       Dilatometer_GetEdge(&val, 1); 
+}
+
+/**
+ * Overlays a line over the given edge position
+ */
+void Draw_Edge(double edge)
+{
+       CvScalar value;
+       value.val[0]=244;
+       for( int i = 0; i < g_srcGray->rows; i++)
+       {
+               cvSet2D(g_edges,i,edge,value);
+       }
+       cvShowImage("display", g_edges);
+       cvWaitKey(0);   
+       //cvSaveImage("test_edge_avg.jpg",g_edges,0);
+}
+
+/* // Test algorithm
+static void Dilatometer_GetImageTest( )
+{      
+       //Generates Test image
+       //Dilatometer_TestImage();
+       
+       //Load Test image
+       g_srcGray = cvLoadImageM ("testimage4.jpg",CV_LOAD_IMAGE_GRAYSCALE );
+}*/
+
+/**
+ * For testing purposes
+ */
+int main(int argc, char ** argv)
+{
+       //cvNamedWindow( "display", CV_WINDOW_AUTOSIZE );// Create a window for display.
+       //gettimeofday(&start, NULL);
+       test_left = 100;
+       test_right = 500;
+       Dilatometer_Init();
+       
+       cvNamedWindow( "display", CV_WINDOW_AUTOSIZE);
+       //double width;
+       
+       double edge;
+       Dilatometer_GetEdge(&edge,20000);
+       //For testing purposes, overlay the given average line over the image
+       //Draw_Edge(edge);
+       
+       cvDestroyWindow("display");
+
+       Dilatometer_Cleanup();
+}
+
diff --git a/testing/Camera/dilatometer/dilatometer.h b/testing/Camera/dilatometer/dilatometer.h
new file mode 100644 (file)
index 0000000..7bb9447
--- /dev/null
@@ -0,0 +1,17 @@
+/**
+ * @file dilatometer.h
+ * @brief Declarations for functions to deal with dilatometer
+ */
+
+#include "common.h"
+
+//Threshold to determine the edge of the can
+#define THRES 230
+
+//Number of samples of the image to take
+#define SAMPLES 600
+
+extern void Dilatometer_Init(); // Initialise the dilatometer
+extern void Dilatometer_Cleanup(); // Cleanup
+extern bool Dilatometer_Read( double * value); // Read the Dilatometer
+
diff --git a/testing/Camera/dilatometer/microscope.c b/testing/Camera/dilatometer/microscope.c
new file mode 100644 (file)
index 0000000..e388073
--- /dev/null
@@ -0,0 +1,246 @@
+/**
+ * @file microscope.c
+ * @purpose Implementation of microscope related functions
+ */
+
+#include "cv.h"
+#include "highgui_c.h"
+#include "microscope.h"
+#include <math.h>
+
+// test positions
+static double test_left, test_right;
+
+// Canny Edge algorithm variables
+int lowThreshold = 30;
+int ratio = 3;
+int kernel_size = 3;
+
+/** Buffer for storing image data. Stored as a  **/
+static CvMat * g_srcRGB  = NULL; // Source Image
+static CvMat * g_srcGray = NULL; // Gray scale of source image
+static CvMat * g_edges          = NULL; // Detected Edges
+static CvMat * g_data    = NULL; // Image to mask edges onto
+
+
+/** Camera capture pointer **/
+static CvCapture * g_capture = NULL;
+
+/**
+ * Create a test image using left as left edge and right as right edge positions
+ */
+void Dilatometer_TestImage()
+{
+       
+       g_srcRGB = cvCreateMat(480, 640, CV_8UC3);
+
+       for( int x = 0; x < 640; ++x)
+       {
+               for (int y = 0; y < 480; ++y)
+               {
+                       CvScalar s; 
+                       for( int i = 0; i < 3; ++i)
+                       {
+                               s.val[i]  =  210 + (rand() % 1000) * 1e-0 - (rand() % 1000) * 1e-0;
+                               // Produce an exponential decay around left edge
+                               if( x < test_left)
+                                       s.val[i] *= exp( (x - test_left) / 25);
+                               else if( x < 320)
+                                       s.val[i] *= exp( (test_left - x) / 25); 
+                               // Produce an exponential decay around right edge
+                               else if( x < test_right)
+                                       s.val[i] *= exp( (x - test_right) / 25); 
+                               else
+                                       s.val[i] *= exp( (test_right - x) / 25);                                
+                       }       
+                       cvSet2D(g_srcRGB,y,x,s);
+               //      if( s.val[0] > 200)
+               //              printf("row: %d, col: %d, %f\n", y, x, s.val[0]); 
+               }
+               
+       }
+       if (g_data == NULL)
+       {
+               g_data = cvCreateMat(g_srcRGB->rows,g_srcRGB->cols,CV_8UC1); //IPL_DEPTH_8U?
+       }
+       cvCvtColor(g_srcRGB,g_data,CV_RGB2GRAY);
+}      
+
+/**
+ * Initialise the dilatometer
+ */
+void Microscope_Init()
+{
+       
+       // Make an initial reading (will allocate memory the first time only).
+       double val;
+       Microscope_Read(&val, 1); 
+}
+
+/**
+ * Cleanup Interferometer stuff
+ */
+void Microscope_Cleanup()
+{
+       if (g_data != NULL)
+               cvReleaseMat(&g_data);
+
+       if (g_capture != NULL)
+               cvReleaseCapture(&g_capture);
+
+}
+
+/**
+ * Get an image from the Dilatometer
+ */
+static void Microscope_GetImage()
+{      
+       //Need to implement camera
+}
+
+void CannyThreshold()
+{
+       
+       if (g_data == NULL)
+       {
+               g_data = cvCreateMat(g_srcGray->rows,g_srcGray->cols,CV_8UC1);
+       }
+
+       if ( g_edges == NULL)
+       {
+               g_edges = cvCreateMat(g_srcGray->rows,g_srcGray->cols,CV_8UC1);
+       }
+       
+       //g_data = 0;
+       cvShowImage("display", g_srcGray);
+       cvWaitKey(0);   
+       // Reduce noise with a kernel 3x3. Input the grayscale source image, output to edges. (0's mean it's determined from kernel sizes)
+       cvSmooth( g_srcGray, g_edges, CV_GAUSSIAN, 9, 9 ,0 ,0 );
+       
+       cvShowImage("display", g_edges);
+       cvWaitKey(0);   
+       
+       // Find the edges in the image
+       lowThreshold = 35;
+       cvCanny( g_edges, g_edges, lowThreshold, lowThreshold*ratio, kernel_size );
+
+       cvShowImage("display", g_edges);
+       cvWaitKey(0);   
+       
+       // Mask the edges over G_data
+       //.copyTo( g_data, g_edges);
+}
+
+// Test algorithm
+static void Microscope_GetImageTest( )
+{      
+       //Generates Test image
+       //Dilatometer_TestImage();
+       
+       //Load Test image
+       g_srcGray = cvLoadImageM ("testimage.jpg",CV_LOAD_IMAGE_GRAYSCALE );
+       CannyThreshold();
+}
+
+
+ /**
+ * Read the microscope image. The value changed will correspond to the new location of the edge.
+ * @param val - Will store the read value if successful
+ * @param samples - Number of rows to scan (increasing will slow down performance!)
+ * @returns true on successful read
+ */
+bool Microscope_Read( double * value, int samples)
+{
+       bool result = false; 
+       double average = 0;
+       // Get the image from the camera
+       Microscope_GetImageTest();
+       
+       int width = g_edges->cols;
+       int height = g_edges->rows;
+       
+       // If the number of samples is greater than the image height, sample every row
+       if( samples > height)
+       {
+               samples = height;
+       }
+       
+       int sample_height;
+       int num_edges = 0;      // Number of edges. if each sample location has an edge, then num_edges = samples
+
+       for (int i=0; i<samples; i++)
+       {
+               // Determine the position in the rows to find the edges. 
+               // This will give you a number of evenly spaced samples
+               sample_height = ceil(height * (i + 1) / samples) -1;
+               
+               // Need to go through each pixel of a row and find all the locations of a line. If there is more than one pixel, average it. note this only works if the canny edge algorithm returns lines about the actual line (no outliers).
+               
+               int edge_location=0;
+               int num=0;
+               for ( int col = 0; col < width; col++)
+               {
+                       // Count the number of points
+                       // Get the threshold of the pixel at the current location
+                       CvScalar value = cvGet2D(g_edges, sample_height, col);
+                       //printf("row: %d, col: %d, value: %f\n",sample_height, col, value.val[0]);
+                       if( value.val[0]> THRES)
+                       {
+                               edge_location += col;
+                               num++;
+                       }
+               }
+               if( num > 0)
+               {
+                       average += ( edge_location / num );
+                       num_edges++;
+                       printf("average %f\n", average/num_edges);
+               }
+       }
+       if (num_edges > 0)
+               average /= num_edges;
+       
+       if( average > 0)
+       {       
+               result = true; //Successfully found an edge
+               *value = average;
+       }
+       return result;
+}
+
+// Overlays a line over the given edge position
+void Draw_Edge(double edge)
+{
+       CvScalar value;
+       value.val[0]=244;
+       for( int i = 0; i < g_srcGray->rows; i++)
+       {
+               cvSet2D(g_edges,i,edge,value);
+       }
+       cvShowImage("display", g_edges);
+       cvWaitKey(0);   
+}
+
+/**
+ * For testing purposes
+ */
+int main(int argc, char ** argv)
+{
+       //cvNamedWindow( "display", CV_WINDOW_AUTOSIZE );// Create a window for display.
+       //gettimeofday(&start, NULL);
+       test_left = 100;
+       test_right = 500;
+       Microscope_Init();
+       
+       cvNamedWindow( "display", CV_WINDOW_AUTOSIZE);
+//     cvShowImage("display", g_data);
+//     cvWaitKey(0);   
+       double width;
+       
+       double edge;
+       Microscope_Read(&edge,15);
+       //For testing purposes, overlay the given average line over the image
+       Draw_Edge(edge);
+
+}
+
diff --git a/testing/Camera/dilatometer/microscope.h b/testing/Camera/dilatometer/microscope.h
new file mode 100644 (file)
index 0000000..ca63b5e
--- /dev/null
@@ -0,0 +1,14 @@
+/**
+ * @file microscope.h
+ * @brief Declarations for functions to deal with microscope
+ */
+
+#include "common.h"
+
+//Threshold to determine the edge of the can
+#define THRES 230
+
+extern void Microscope_Init(); // Initialise the dilatometer
+extern void Microscope_Cleanup(); // Cleanup
+extern bool Microscope_Read( double * value, int samples); // Read the Microscope
+
diff --git a/testing/Camera/dilatometer/stream.c b/testing/Camera/dilatometer/stream.c
new file mode 100644 (file)
index 0000000..e1e23c1
--- /dev/null
@@ -0,0 +1,68 @@
+#include "cv.h"
+#include "highgui_c.h"
+#include <string.h>
+#include <stdio.h>
+
+/*-------------------------------------------------------------------
+
+compile with:
+-I/usr/include/opencv -I/usr/include/opencv2/highgui -L/usr/lib -lopencv_highgui -lopencv_core -lopencv_ml -lopencv_imgproc
+
+--------------------------------------------------------------------*/
+
+int storeFrame( CvCapture* capture)
+{
+       IplImage *frame;
+       CvMat* jpg;
+       
+       //FILE *fp = fopen ("test.jpg", "wb");
+
+       int p[3];
+       p[0] = CV_IMWRITE_JPEG_QUALITY;
+       p[1] = 100;     //quality value. 0-100
+       p[2] = 0;
+               
+       frame = cvQueryFrame(capture);
+       if( frame == NULL)
+               return 0;       //error
+       cvSaveImage("../web/images/test.JPG",frame,p);
+       //jpg = cvEncodeImage(".jpg", frame,p); 
+       /*pass buf to client, write to file on client*/
+       //fwrite(jpg->data.ptr,1,jpg->rows*jpg->cols, fp);
+       
+       //decjpg = cvDecodeImage(jpg, CV_LOAD_IMAGE_COLOR);
+       //cvShowImage( "Display window", decjpg );  
+                       
+       //cvWaitKey(0);
+       cvReleaseImageHeader(&frame);
+       //cvReleaseMat(&jpg);
+       //fclose( fp);
+       return 1;
+}
+
+int main (int argc, char** argv)
+{
+       CvCapture* capture;
+       //cvNamedWindow( "Display window", CV_WINDOW_AUTOSIZE );// Create a window for display.
+       //Get capture structure for camera, -1 refers to any camera device.
+       //If multiple cameras used, need to use specific camera ID
+       capture = cvCreateCameraCapture(-1);
+       //If cvCreateCameraCapture returns NULL there is an error with the camera
+       if( capture == NULL)
+               return -1;
+
+       cvSetCaptureProperty (capture, CV_CAP_PROP_FOURCC, 'MJPEG');
+
+       while(1)
+       {
+               if( !storeFrame( capture))
+                       return -1;
+               printf("enter to continue");
+               getchar();
+               //sleep(1);     //for now just to make the camera take 1 shot a second, as that's all my camera seems to be able to take/save (camera or function causing this? is 1 second per frame enough?)
+       }
+       
+       //Need to determine how the function is called in respect to system. just leave it running with a while loop? will something turn it on and off? will the function be called once from elsewhere?
+       cvReleaseCapture( &capture);
+}
+
diff --git a/testing/interferometer/Readme.md b/testing/interferometer/Readme.md
new file mode 100644 (file)
index 0000000..1692725
--- /dev/null
@@ -0,0 +1 @@
+These are the interferometer test files, which once resided in the main `server` directory. They have been moved here because this code is no longer in use.
diff --git a/testing/interferometer/interferometer.c b/testing/interferometer/interferometer.c
new file mode 100644 (file)
index 0000000..4861318
--- /dev/null
@@ -0,0 +1,288 @@
+/**
+ * @file interferometer.c
+ * @purpose Implementation of interferometer related functions
+ */
+
+#include "cv.h"
+#include "highgui_c.h"
+#include "interferometer.h"
+#include <math.h>
+
+/** Buffer for storing image data. Stored as a single intensity value for the laser light **/
+static CvMat * g_data = NULL;
+
+
+/** Camera capture pointer **/
+static CvCapture * g_capture = NULL;
+
+
+struct timeval start;
+
+#define PI 3.141592
+
+// For testing purposes
+double test_omega = 0.05;
+double test_angle = PI/2;
+double test_noise[] = {0,0,0.02};
+double test_phase = 0;
+double test_intensity = 1.0;
+
+
+static void Interferometer_TestSinusoid()
+{
+       if (g_capture == NULL)
+       {
+               g_capture = cvCreateCameraCapture(0);
+       }
+
+       // Get image from camera
+       IplImage * img = cvQueryFrame(g_capture);
+
+       // Convert to CvMat
+       CvMat stub;
+       CvMat * background = cvGetMat(img, &stub, 0, 0);
+       // ... Honestly, I have no idea what the "stub" is for
+
+       if (g_data == NULL)
+       {
+               g_data = cvCreateMat(background->rows, background->cols, CV_32FC3);
+       }
+
+       //cvShowImage("background", background);
+
+       for (int x = 0; x < g_data->cols-1; ++x)
+       {
+               for (int y = 0; y < g_data->rows-1; ++y)
+               {
+                       // Calculate pure sine in test direction
+                       double r = x*cos(test_angle) + y*sin(test_angle);
+                       double value = 0.5*test_intensity*(1+sin(test_omega*r + test_phase));
+
+                       CvScalar s; 
+                       s.val[0] = 0; s.val[1] = 0; s.val[2] = value;
+                       CvScalar b = cvGet2D(background, y, x);
+
+
+                       // Add noise & background image
+
+                       // Get the order the right way round
+                       double t = b.val[0];
+                       b.val[0] = b.val[2];
+                       b.val[2] = t;
+                       for (int i = 0; i < 3; ++i)
+                       {
+                                       
+                               s.val[i] += (rand() % 1000) * 1e-3 * test_noise[i];
+                               s.val[i] += b.val[i] / 255; // Camera image is 0-255
+                       }
+
+                       //printf("set %d,%d\n", x, y);
+
+               
+
+                       cvSet2D(g_data,y, x, s);
+               }
+       }       
+
+
+}
+
+
+/**
+ * Get an image from the Interferometer
+ */
+static void Interferometer_GetImage()
+{
+
+
+       Interferometer_TestSinusoid();
+       //TODO: Implement camera 
+
+}
+
+/**
+ * Initialise the Interferometer
+ */
+void Interferometer_Init()
+{
+       
+       // Make an initial reading (will allocate memory the first time only).
+       Interferometer_Read(1); 
+}
+
+/**
+ * Cleanup Interferometer stuff
+ */
+void Interferometer_Cleanup()
+{
+       if (g_data != NULL)
+               cvReleaseMat(&g_data);
+
+       if (g_capture != NULL)
+               cvReleaseCapture(&g_capture);
+
+}
+
+/**
+ * Read the interferometer; gets the latest image, processes it, spits out a single number
+ * @param samples - Number of columns to scan (increasing will slow down performance!)
+ * @returns Value proportional to the change in interferometer path length since the last call to this function
+ */
+double Interferometer_Read(int samples)
+{
+
+
+
+
+       // Get the latest image
+       Interferometer_GetImage();
+       // Frequency of the sinusoid
+       static double omega = 0;
+       // Stores locations of nodes
+       static int nodes[MAXNODES];
+       // Current phase
+       static double phase = 0;
+
+       // Phase
+       double cur_phase = 0;
+
+       int xstep = g_data->cols / (samples+1);
+
+       // Used for testing to see where the nodes are identified
+       // (Can't modify g_data)
+       static CvMat * test_overlay = NULL;
+       if (test_overlay == NULL)
+       {
+               // Creates a memory leak; don't do this in the final version!
+               test_overlay = cvCreateMat(g_data->rows, g_data->cols, CV_32FC3);
+       }
+       cvZero(test_overlay);
+       //cvCopy(g_data, test_overlay, NULL);
+
+       // For each column to sample
+       for (int x = xstep; x < g_data->cols; x += xstep)
+       {
+               
+               double avg = 0.5; //TODO: Calculate from image
+               double threshold_dif = 0; //TODO: Pick this value
+
+               int num_nodes = 0;
+               
+               // Find nodes
+               for (int y = 1; y < g_data->rows-2 && num_nodes < MAXNODES; ++y)
+               {
+                       if (num_nodes == 0 || abs(nodes[num_nodes-1] - y) > 1)
+                       {
+                               // A "node" is defined where the ajacent points are on opposite sides of the avg
+                               double ldif = INTENSITY(cvGet2D(g_data, y-1,x)) - avg;
+                               double rdif = INTENSITY(cvGet2D(g_data, y+1,x)) - avg;
+
+                               // If that is the case, the product of the differences will be negative
+                               if (ldif * rdif < -threshold_dif)
+                               {
+
+                                       nodes[num_nodes++] = y;
+
+                                       // Put a white line on the overlay to indicate the node was found
+                                       for (int xx = 0; xx < g_data->cols; ++xx)
+                                       {
+                                               CvScalar s; // = cvGet2D(g_data, y, xx);
+                                               s.val[0] = 1; s.val[1] = 1; s.val[2] = 1;
+                                               cvSet2D(test_overlay, y, xx, s);
+                                       }
+                               }
+                       }
+               }
+
+               // Insufficient nodes found to continue
+               if (num_nodes < 2)
+               {
+                       --samples;
+                       continue;
+               }
+
+               // Estimate angular frequency from two nodes TODO: Average between nodes
+               double slice_omega = (PI*(num_nodes-1)) / (nodes[num_nodes-1] - nodes[0]);
+               //printf("SLICE: %f vs %f\n", slice_omega, test_omega);
+
+               double slice_phase = 0;
+               for (int i = 0; i < num_nodes; ++i)
+               {
+                       double this_phase = ((double)(i)*PI - slice_omega * nodes[i]);
+                       //printf("Node %d gives phase %f\n", i, this_phase);
+                       slice_phase += this_phase;
+               }
+               slice_phase /= num_nodes;
+               cur_phase += slice_phase;
+       }
+
+       // Average over samples
+       if (samples == 0)
+               return 0;
+
+       cur_phase /= samples;
+
+
+
+       // Get phase change since last call, save current phase
+       double result = (cur_phase - phase);
+
+       // HACK
+       if (abs(result) > 0.5*PI)
+       {
+               if (result > 0)
+                       result -= PI;
+               else
+                       result += PI;
+       }       
+       phase = cur_phase;
+
+       // Display the image with lines to indicate results of data processing
+       //cvShowImage("nodes", test_overlay);
+       //cvWaitKey(1);
+       cvAdd(test_overlay, g_data, test_overlay, NULL);
+       cvShowImage("overlay", test_overlay);
+       cvWaitKey(1);
+       return result;
+
+}
+
+/**
+ * For testing purposes
+ */
+int main(int argc, char ** argv)
+{
+       //cvNamedWindow( "display", CV_WINDOW_AUTOSIZE );// Create a window for display.
+       gettimeofday(&start, NULL);
+
+       //Interferometer_Read(1);
+       //exit(EXIT_SUCCESS);
+
+       Interferometer_Init();
+
+       double sum = 0;
+       double last_phase = test_phase;
+
+       struct timeval now;
+       double time = 0;
+
+       while (time < 20)
+       {
+               gettimeofday(&now, NULL);
+               time = TIMEVAL_DIFF(now, start);
+               
+               test_phase = 0.5*PI*sin(time);
+
+               
+               double delta = Interferometer_Read(1);
+               sum += delta;
+       
+               printf("%f\t%f\t%f\t%f\t%f\n", time, test_phase - last_phase, test_phase, delta, sum);  
+
+               last_phase = test_phase;
+               //break;
+       }
+       
+}
+
+
diff --git a/testing/interferometer/interferometer.h b/testing/interferometer/interferometer.h
new file mode 100644 (file)
index 0000000..f545463
--- /dev/null
@@ -0,0 +1,18 @@
+/**
+ * @file interferometer.h
+ * @purpose Declarations for functions to deal with interferometer
+ */
+
+#include "common.h"
+
+//#define INTENSITY(rgb) ((rgb).val[0]*(rgb).val[0] + (rgb).val[1]*(rgb).val[1] + (rgb).val[2]*(rgb).val[2])
+#define INTENSITY(rgb) ((rgb).val[2])
+
+#define MAXNODES 100 //TODO: Choose value based on real data
+
+extern void Interferometer_Init(); // Initialise the interferometer
+extern void Interferometer_Cleanup(); // Cleanup
+extern double Interferometer_Read(); // Read the interferometer
+
+
+
diff --git a/testing/interferometer/intertest.sh b/testing/interferometer/intertest.sh
new file mode 100755 (executable)
index 0000000..f3012ad
--- /dev/null
@@ -0,0 +1,15 @@
+rm intertest
+make intertest
+./intertest > test.dat
+
+cmd="set title \"Interferometer Test\""
+cmd="$cmd; set xlabel \"Time (s)\""
+cmd="$cmd; set ylabel \"Phase (rad)\""
+cmd="$cmd; plot \"test.dat\" u 1:3 t \"Specified\" w l, \"test.dat\" u 1:5 t \"Calculated\" w p"
+gnuplot --persist -e "$cmd"
+
+cmd="set title \"Interferometer Test\""
+cmd="$cmd; set xlabel \"Time (s)\""
+cmd="$cmd; set ylabel \"Delta Phase (rad)\""
+cmd="$cmd; plot \"test.dat\" u 1:2 t \"Specified\" w l, \"test.dat\" u 1:4 t \"Measured\" w p"
+gnuplot --persist -e "$cmd"

UCC git Repository :: git.ucc.asn.au