view Plot.c @ 258:5296f3bcd160

Implement DDS clients reconnect On network send() failures try to reconnect to the server before returning an error. This allows to restart the network servers controlling the DDSes wiothout having to restart the clients.
author Daniele Nicolodi <daniele.nicolodi@obspm.fr>
date Tue, 16 Jun 2015 14:31:35 +0200
parents a3494d2806ee
children
line wrap: on
line source

#include <ansi_c.h>
#include <userint.h>

#include "utils.h"
#include "FXPlot.h"
#include "Plot.h"

#define PLOT_LINE_COLOR VAL_RED 

void Plot_InitPanel(Plot_Data *Instance, const char *title, double ymin, double ymax, int parent, int control)
{
	if ((Instance->PlotPanel = LoadPanel (0, "FXPlot.uir", PLOTPANEL)) < 0)
		return;
	
	SetPanelAttribute(Instance->PlotPanel, ATTR_TITLE, title);  
	SetPanelAttribute(Instance->PlotPanel, ATTR_CALLBACK_DATA, (void *)Instance);
	Instance->active = TRUE;
	Instance->parent = parent;
	Instance->control = control;
	Instance->IndexPoint = 0;
	Instance->Mean = 0;
	Instance->Slope = 0;
	Instance->ADev = 0;
	Instance->Frequencies = calloc(MAXPOINTSNUMBER, sizeof(double));
	DisplayPanel(Instance->PlotPanel);
	
	SetCtrlVal(Instance->PlotPanel, PLOTPANEL_MIN, ymin);
	SetCtrlVal(Instance->PlotPanel, PLOTPANEL_MAX, ymax);
	
	if ((ymin != 0.0) && (ymax != 0.0)) {
		/* manual scaling */
		SetCtrlVal(Instance->PlotPanel, PLOTPANEL_MIN, ymin);
		SetCtrlVal(Instance->PlotPanel, PLOTPANEL_MAX, ymax);
		SetAxisScalingMode(Instance->PlotPanel, PLOTPANEL_FREQPLOT, VAL_LEFT_YAXIS, VAL_MANUAL, ymin, ymax);
	} else {
		/* auto scaling */
		SetCtrlVal(Instance->PlotPanel, PLOTPANEL_CHECKBOX_AUTOSCALE, TRUE);
		SetAxisScalingMode(Instance->PlotPanel, PLOTPANEL_FREQPLOT, VAL_LEFT_YAXIS, VAL_AUTOSCALE, 0, 0);
	}
}


void Plot_ClosePanel(Plot_Data * Instance)
{
	Instance->active = FALSE;
	free(Instance->Frequencies);
	SetCtrlVal(Instance->parent, Instance->control, FALSE);
	DiscardPanel(Instance->PlotPanel); 
}


void Plot_AddFrequency(Plot_Data * Instance, double Freq)
{
	double Drift = 0;
	int DeDrift;
	int N = 0;

	double Mean  = Instance->Mean;
	double Slope = Instance->Slope;
	double ADev  = Instance->ADev; 
	
	/* Correct Freq with drift (feed forward) if dedrift is on */
	GetCtrlVal(Instance->PlotPanel, PLOTPANEL_CHECKBOX_DEDRIFT, &DeDrift);
	if (DeDrift) {
		GetCtrlVal(Instance->PlotPanel, PLOTPANEL_DEDRIFT, &Drift);
		Freq -= ((double) Instance->IndexPoint)*Drift;
	}
	
	/* Add Freq to graph plot */
	Instance->Frequencies[Instance->IndexPoint++] = Freq;
	N = Instance->IndexPoint;
	
	if (N > 1) {
		/* adev and slope computation need at least 2 data points */
		Instance->Slope = (Slope*(N-2) + 6*(Freq-Mean)/N)/(N+1);
		SetCtrlVal(Instance->PlotPanel, PLOTPANEL_SLOPE, Instance->Slope);
		Instance->ADev = sqrt( ( ADev*ADev*(N-2) + 0.5*pow(Freq-Instance->Frequencies[N-2],2) ) / (N-1));
		SetCtrlVal(Instance->PlotPanel, PLOTPANEL_ADEV, Instance->ADev);
	}
	Instance->Mean = (Mean*(N-1)+Freq)/N;
	SetCtrlVal(Instance->PlotPanel, PLOTPANEL_MEAN, Instance->Mean);
	
	/* if too many points recorded restart */
	if (N > MAXPOINTSNUMBER - 2) {
		Instance->IndexPoint = 0;
		Instance->Mean = 0;
		Instance->Slope = 0;
		Instance->ADev = 0;
		SetCtrlVal(Instance->PlotPanel,PLOTPANEL_MEAN, 0.0);
		SetCtrlVal(Instance->PlotPanel,PLOTPANEL_SLOPE, 0.0);
		SetCtrlVal(Instance->PlotPanel,PLOTPANEL_ADEV, 0.0);
	}
	
	DeleteGraphPlot(Instance->PlotPanel, PLOTPANEL_FREQPLOT, -1, VAL_IMMEDIATE_DRAW);
	PlotY(Instance->PlotPanel, PLOTPANEL_FREQPLOT, Instance->Frequencies, Instance->IndexPoint,
		VAL_DOUBLE, VAL_THIN_LINE, VAL_EMPTY_SQUARE, VAL_SOLID, 1, PLOT_LINE_COLOR);
	
	int autoscale;
	GetCtrlVal(Instance->PlotPanel, PLOTPANEL_CHECKBOX_AUTOSCALE, &autoscale);
	if (autoscale) {
		/* update plot limits */
		double ymin, ymax;
		GetAxisScalingMode(Instance->PlotPanel, PLOTPANEL_FREQPLOT,VAL_LEFT_YAXIS, NULL, &ymin, &ymax);
		SetCtrlVal(Instance->PlotPanel, PLOTPANEL_MIN, ymin);
		SetCtrlVal(Instance->PlotPanel, PLOTPANEL_MAX, ymax);
		/* adjust control limits */
		SetCtrlAttribute(Instance->PlotPanel, PLOTPANEL_MIN, ATTR_MAX_VALUE, ymax);
		SetCtrlAttribute(Instance->PlotPanel, PLOTPANEL_MAX, ATTR_MIN_VALUE, ymin);
	}
}


/* callbacks */

int CVICALLBACK CB_PlotEvent(int panel, int event,
		void *callbackData, int eventData1, int eventData2)
{
	switch (event)
	{
		case EVENT_CLOSE:
			Plot_Data *data;
			GetPanelAttribute (panel, ATTR_CALLBACK_DATA, &data);
			Plot_ClosePanel(data);
			break;
	
		case EVENT_KEYPRESS:
			int keycode = GetKeyPressEventVirtualKey(eventData2);
			int index;
			double step;
			switch (keycode)
			{
				case 2304: /* right arrow */
					GetCtrlIndex(panel, PLOTPANEL_SCALINGSTEP, &index);
					if (index < 10) {
						SetCtrlIndex(panel, PLOTPANEL_SCALINGSTEP, ++index);
						GetCtrlVal(panel, PLOTPANEL_SCALINGSTEP, &step);
						SetCtrlAttribute(panel, PLOTPANEL_MIN, ATTR_INCR_VALUE, step);
						SetCtrlAttribute(panel, PLOTPANEL_MAX, ATTR_INCR_VALUE, step);
					}
					break;
				case 2048: /* left arrow */
					GetCtrlIndex(panel, PLOTPANEL_SCALINGSTEP, &index);
					if (index > 0) {
						SetCtrlIndex(panel, PLOTPANEL_SCALINGSTEP, --index);
						GetCtrlVal(panel, PLOTPANEL_SCALINGSTEP, &step);
						SetCtrlAttribute(panel, PLOTPANEL_MIN, ATTR_INCR_VALUE, step);
						SetCtrlAttribute(panel, PLOTPANEL_MAX, ATTR_INCR_VALUE, step);
					}
					break;
			}
			break;
	}
	return 0;
}


int CVICALLBACK Plot_CB_ChangeYLim (int panel, int control, int event,
		void *callbackData, int eventData1, int eventData2)
{
	double ymin, ymax;
	
	switch (event)
	{
		case EVENT_COMMIT:
			GetCtrlVal(panel, PLOTPANEL_MIN, &ymin);
			GetCtrlVal(panel, PLOTPANEL_MAX, &ymax);
			/* adjust control limits */
			SetCtrlAttribute(panel, PLOTPANEL_MIN, ATTR_MAX_VALUE, ymax);
			SetCtrlAttribute(panel, PLOTPANEL_MAX, ATTR_MIN_VALUE, ymin);
			/* disable autoscaling */
			SetCtrlVal(panel, PLOTPANEL_CHECKBOX_AUTOSCALE, FALSE);
			SetAxisScalingMode(panel, PLOTPANEL_FREQPLOT, VAL_LEFT_YAXIS, VAL_MANUAL, ymin, ymax);
			break;
	}
	return 0;
}


int CVICALLBACK Plot_CB_ChangeAutoScale (int panel, int control, int event,
		void *callbackData, int eventData1, int eventData2)
{
	int autoscale = FALSE;
	double ymin, ymax;
	
	switch (event)
	{
		case EVENT_COMMIT:
			GetCtrlVal(panel, PLOTPANEL_CHECKBOX_AUTOSCALE, &autoscale);
			if (autoscale) {
				SetAxisScalingMode(panel, PLOTPANEL_FREQPLOT, VAL_LEFT_YAXIS, VAL_AUTOSCALE, 0, 0);
				GetAxisScalingMode(panel, PLOTPANEL_FREQPLOT,VAL_LEFT_YAXIS, NULL, &ymin, &ymax);
				SetCtrlVal(panel, PLOTPANEL_MIN, ymin);
				SetCtrlVal(panel, PLOTPANEL_MAX, ymax);
				/* adjust control limits */
				SetCtrlAttribute(panel, PLOTPANEL_MIN, ATTR_MAX_VALUE, ymax);
				SetCtrlAttribute(panel, PLOTPANEL_MAX, ATTR_MIN_VALUE, ymin);
			} else {
				GetCtrlVal(panel, PLOTPANEL_MIN, &ymin);
				GetCtrlVal(panel, PLOTPANEL_MAX, &ymax);
				SetAxisScalingMode(panel, PLOTPANEL_FREQPLOT, VAL_LEFT_YAXIS, VAL_MANUAL, ymin, ymax);
			}
			break;
	}
	return 0;
} 


int  CVICALLBACK Plot_CB_ChangeScalingStep(int panel, int control, int event,
		void *callbackData, int eventData1, int eventData2)
{
	double step;

	switch (event)
	{
		case EVENT_COMMIT:
			GetCtrlVal(panel, PLOTPANEL_SCALINGSTEP, &step);
			SetCtrlAttribute(panel, PLOTPANEL_MIN, ATTR_INCR_VALUE, step);
			SetCtrlAttribute(panel, PLOTPANEL_MAX, ATTR_INCR_VALUE, step);
			break;
	}
	return 0;
}


int CVICALLBACK Plot_CB_Reset (int panel, int control, int event,
		void *callbackData, int eventData1, int eventData2)
{
	Plot_Data *data;
	switch (event)
	{
		case EVENT_COMMIT:
			GetPanelAttribute (panel, ATTR_CALLBACK_DATA, &data);
			data->IndexPoint = 0;
			data->Mean = 0;
			data->Slope = 0;
			data->ADev = 0;
			break;
	}
	return 0;
}


int CVICALLBACK Plot_CB_GetDrift (int panel, int control, int event,
		void *callbackData, int eventData1, int eventData2)
{
	Plot_Data *data;
	int dedrift;
	double drift;
	
	switch (event)
	{
		case EVENT_COMMIT:
			GetPanelAttribute(panel, ATTR_CALLBACK_DATA, &data);  
			GetCtrlVal(panel, PLOTPANEL_CHECKBOX_DEDRIFT, &dedrift);
			if (dedrift) {
				GetCtrlVal(panel, PLOTPANEL_DEDRIFT, &drift);
				drift += data->Slope;
				SetCtrlVal(panel, PLOTPANEL_DEDRIFT, drift);
				data->IndexPoint = 0;
				data->Mean = 0;
				data->Slope = 0;
				data->ADev = 0;
			} else
				SetCtrlVal(panel,PLOTPANEL_DEDRIFT, data->Slope);
			break;
	}
	return 0;
}


int CVICALLBACK Plot_CB_ChangeDrift (int panel, int control, int event,
		void *callbackData, int eventData1, int eventData2)
{
	int dedrift;
	Plot_Data *data;
	
	switch (event)
	{
		case EVENT_COMMIT:
			GetCtrlVal(panel, PLOTPANEL_CHECKBOX_DEDRIFT, &dedrift);
			if (dedrift) {
				GetPanelAttribute (panel, ATTR_CALLBACK_DATA, &data);
				data->IndexPoint = 0;
				data->Mean = 0;
				data->Slope = 0;
				data->ADev = 0;
			}
			break;
	}
	return 0;
}