Browse Source

DATAQ SDK channel calibration assistance working.

Neal Wilson 11 years ago
parent
commit
91559c626b
1 changed files with 191 additions and 7 deletions
  1. 191
    7
      src/dataqsdk.w

+ 191
- 7
src/dataqsdk.w View File

825
 		void startCalibration();
825
 		void startCalibration();
826
 		void stopCalibration();
826
 		void stopCalibration();
827
 		void resetCalibration();
827
 		void resetCalibration();
828
+		void updateInput(Measurement measure);
829
+		void updateOutput(Measurement measure);
830
+	private:
831
+		QPushButton *startButton;
832
+		QPushButton *resetButton;
833
+		QPushButton *stopButton;
834
+		@<DATAQ SDK device settings@>@;
835
+		DataqSdkDevice *calibrationDevice;
836
+		LinearCalibrator *calibrator;
837
+		QLineEdit *currentMeasurement;
838
+		QLineEdit *minimumMeasurement;
839
+		QLineEdit *maximumMeasurement;
840
+		QLineEdit *averageMeasurement;
841
+		QLineEdit *currentMapped;
842
+		QLineEdit *minimumMapped;
843
+		QLineEdit *maximumMapped;
844
+		QLineEdit *averageMapped;
845
+		int rmCount;
846
+		int cmCount;
847
+		double rmin;
848
+		double rmax;
849
+		double rmean;
850
+		double cmin;
851
+		double cmax;
852
+		double cmean;
828
 };
853
 };
829
 
854
 
855
+@ Private members that hold minimum and maximum aggregate data for channel
856
+calibration will be initialized to the maximum and minimum values available for
857
+the |double| type respectively. This guarantees that the first measurement will
858
+overwrite these values. This is done with |std::numeric_limits| so we require a
859
+header to be included to gain access to this.
860
+
861
+@<Header files to include@>=
862
+#include <limits>
863
+
830
 @ The constructor sets up the interface. Calibration settings line edits need
864
 @ The constructor sets up the interface. Calibration settings line edits need
831
 to have numeric validators added.
865
 to have numeric validators added.
832
 
866
 
833
 @<DataqSdkDeviceConfWidget implementation@>=
867
 @<DataqSdkDeviceConfWidget implementation@>=
834
 DataqSdkChannelConfWidget::DataqSdkChannelConfWidget(DeviceTreeModel *model,
868
 DataqSdkChannelConfWidget::DataqSdkChannelConfWidget(DeviceTreeModel *model,
835
                                                      const QModelIndex &index)
869
                                                      const QModelIndex &index)
836
-	: BasicDeviceConfigurationWidget(model, index)
870
+	: BasicDeviceConfigurationWidget(model, index),
871
+	startButton(new QPushButton(tr("Start"))),
872
+	resetButton(new QPushButton(tr("Reset"))),
873
+	stopButton(new QPushButton(tr("Stop"))),
874
+	calibrator(new LinearCalibrator),
875
+	currentMeasurement(new QLineEdit), minimumMeasurement(new QLineEdit),
876
+	maximumMeasurement(new QLineEdit), averageMeasurement(new QLineEdit),
877
+	currentMapped(new QLineEdit), minimumMapped(new QLineEdit),
878
+	maximumMapped(new QLineEdit), averageMapped(new QLineEdit),
879
+	rmCount(0), cmCount(0),
880
+	rmin(std::numeric_limits<double>::max()),
881
+	rmax(std::numeric_limits<double>::min()), rmean(0),
882
+	cmin(std::numeric_limits<double>::max()),
883
+	cmax(std::numeric_limits<double>::min()), cmean(0)
837
 {
884
 {
885
+	@<Find DATAQ SDK device settings from parent node@>@;
886
+	resetButton->setEnabled(false);
887
+	stopButton->setEnabled(false);
888
+	connect(startButton, SIGNAL(clicked()), this, SLOT(startCalibration()));
889
+	connect(resetButton, SIGNAL(clicked()), this, SLOT(resetCalibration()));
890
+	connect(stopButton, SIGNAL(clicked()), this, SLOT(stopCalibration()));
838
 	QVBoxLayout *layout = new QVBoxLayout;
891
 	QVBoxLayout *layout = new QVBoxLayout;
839
 	QFormLayout *topLayout = new QFormLayout;
892
 	QFormLayout *topLayout = new QFormLayout;
840
 	QLineEdit *columnEdit = new QLineEdit;
893
 	QLineEdit *columnEdit = new QLineEdit;
848
 	layout->addLayout(topLayout);
901
 	layout->addLayout(topLayout);
849
 	QLabel *calibrationLabel = new QLabel(tr("Calibration settings"));
902
 	QLabel *calibrationLabel = new QLabel(tr("Calibration settings"));
850
 	layout->addWidget(calibrationLabel);
903
 	layout->addWidget(calibrationLabel);
904
+	QHBoxLayout *calibrationLayout = new QHBoxLayout;
851
 	QFormLayout *calibrationControlsLayout = new QFormLayout;
905
 	QFormLayout *calibrationControlsLayout = new QFormLayout;
852
 	QLineEdit *measuredLowerEdit = new QLineEdit;
906
 	QLineEdit *measuredLowerEdit = new QLineEdit;
853
 	measuredLowerEdit->setText("0");
907
 	measuredLowerEdit->setText("0");
866
 	QLineEdit *sensitivityEdit = new QLineEdit;
920
 	QLineEdit *sensitivityEdit = new QLineEdit;
867
 	sensitivityEdit->setText("0");
921
 	sensitivityEdit->setText("0");
868
 	calibrationControlsLayout->addRow(tr("Discrete interval skip"), sensitivityEdit);
922
 	calibrationControlsLayout->addRow(tr("Discrete interval skip"), sensitivityEdit);
869
-	layout->addLayout(calibrationControlsLayout);
870
-	
871
-	// Insert another panel to assist in determining proper calibration values.
872
-	
923
+	QVBoxLayout *calibrationTestLayout = new QVBoxLayout;
924
+	QHBoxLayout *deviceControlLayout = new QHBoxLayout;
925
+	deviceControlLayout->addWidget(startButton);
926
+	deviceControlLayout->addWidget(resetButton);
927
+	deviceControlLayout->addWidget(stopButton);
928
+	QFormLayout *indicatorLayout = new QFormLayout;	
929
+	currentMeasurement->setReadOnly(true);
930
+	minimumMeasurement->setReadOnly(true);
931
+	maximumMeasurement->setReadOnly(true);
932
+	averageMeasurement->setReadOnly(true);
933
+	currentMapped->setReadOnly(true);
934
+	minimumMapped->setReadOnly(true);
935
+	maximumMapped->setReadOnly(true);
936
+	averageMapped->setReadOnly(true);
937
+	indicatorLayout->addRow(tr("Measured Values"), new QWidget);
938
+	indicatorLayout->addRow(tr("Current"), currentMeasurement);
939
+	indicatorLayout->addRow(tr("Minimum"), minimumMeasurement);
940
+	indicatorLayout->addRow(tr("Maximum"), maximumMeasurement);
941
+	indicatorLayout->addRow(tr("Mean"), averageMeasurement);
942
+	indicatorLayout->addRow(tr("Mapped Values"), new QWidget);
943
+	indicatorLayout->addRow(tr("Current Mapped"), currentMapped);
944
+	indicatorLayout->addRow(tr("Minimum Mapped"), minimumMapped);
945
+	indicatorLayout->addRow(tr("Maximum Mapped"), maximumMapped);
946
+	indicatorLayout->addRow(tr("Mean Mapped"), averageMapped);
947
+	calibrationTestLayout->addLayout(deviceControlLayout);
948
+	calibrationTestLayout->addLayout(indicatorLayout);
949
+	calibrationLayout->addLayout(calibrationControlsLayout);
950
+	calibrationLayout->addLayout(calibrationTestLayout);
951
+	layout->addLayout(calibrationLayout);
873
 	@<Get device configuration data for current node@>@;
952
 	@<Get device configuration data for current node@>@;
874
 	for(int i = 0; i < configData.size(); i++)
953
 	for(int i = 0; i < configData.size(); i++)
875
 	{
954
 	{
960
 void DataqSdkChannelConfWidget::updateMeasuredLower(const QString &value)
1039
 void DataqSdkChannelConfWidget::updateMeasuredLower(const QString &value)
961
 {
1040
 {
962
 	updateAttribute("calibrationMeasuredLower", value);
1041
 	updateAttribute("calibrationMeasuredLower", value);
1042
+	calibrator->setMeasuredLower(value.toDouble());
963
 }
1043
 }
964
 
1044
 
965
 void DataqSdkChannelConfWidget::updateMeasuredUpper(const QString &value)
1045
 void DataqSdkChannelConfWidget::updateMeasuredUpper(const QString &value)
966
 {
1046
 {
967
 	updateAttribute("calibrationMeasuredUpper", value);
1047
 	updateAttribute("calibrationMeasuredUpper", value);
1048
+	calibrator->setMeasuredUpper(value.toDouble());
968
 }
1049
 }
969
 
1050
 
970
 void DataqSdkChannelConfWidget::updateMappedLower(const QString &value)
1051
 void DataqSdkChannelConfWidget::updateMappedLower(const QString &value)
971
 {
1052
 {
972
 	updateAttribute("calibrationMappedLower", value);
1053
 	updateAttribute("calibrationMappedLower", value);
1054
+	calibrator->setMappedLower(value.toDouble());
973
 }
1055
 }
974
 
1056
 
975
 void DataqSdkChannelConfWidget::updateMappedUpper(const QString &value)
1057
 void DataqSdkChannelConfWidget::updateMappedUpper(const QString &value)
976
 {
1058
 {
977
 	updateAttribute("calibrationMappedUpper", value);
1059
 	updateAttribute("calibrationMappedUpper", value);
1060
+	calibrator->setMappedUpper(value.toDouble());
978
 }
1061
 }
979
 
1062
 
980
 void DataqSdkChannelConfWidget::updateClosedInterval(bool closed)
1063
 void DataqSdkChannelConfWidget::updateClosedInterval(bool closed)
981
 {
1064
 {
982
 	updateAttribute("calibrationClosedInterval", closed ? "true" : "false");
1065
 	updateAttribute("calibrationClosedInterval", closed ? "true" : "false");
1066
+	calibrator->setClosedRange(closed);
983
 }
1067
 }
984
 
1068
 
985
 void DataqSdkChannelConfWidget::updateSmoothingEnabled(bool enabled)
1069
 void DataqSdkChannelConfWidget::updateSmoothingEnabled(bool enabled)
990
 void DataqSdkChannelConfWidget::updateSensitivity(const QString &value)
1074
 void DataqSdkChannelConfWidget::updateSensitivity(const QString &value)
991
 {
1075
 {
992
 	updateAttribute("calibrationSensitivity", value);
1076
 	updateAttribute("calibrationSensitivity", value);
1077
+	calibrator->setSensitivity(value.toDouble());
1078
+}
1079
+
1080
+@ When calibrating a device, we must know certain information to open a
1081
+connection to the appropriate hardware and know which channel we are interested
1082
+in.
1083
+
1084
+@<DATAQ SDK device settings@>=
1085
+bool autoSelect;
1086
+QString deviceID;
1087
+int channelOfInterest;
1088
+
1089
+@ This information is accessed through the reference element associated with
1090
+the parent node of the current configuration and from the row number of the
1091
+current node.
1092
+
1093
+@<Find DATAQ SDK device settings from parent node@>=
1094
+QDomElement parentReference = model->referenceElement(model->data(index.parent(), Qt::UserRole).toString());
1095
+QDomNodeList deviceConfigData = parentReference.elementsByTagName("attribute");
1096
+QDomElement deviceNode;
1097
+QString configPort;
1098
+QString configAuto;
1099
+for(int i = 0; i < deviceConfigData.size(); i++)
1100
+{
1101
+	deviceNode = deviceConfigData.at(i).toElement();
1102
+	if(deviceNode.attribute("name") == "autoSelect")
1103
+	{
1104
+		autoSelect = (deviceNode.attribute("value") == "true");
1105
+	}
1106
+	else if(deviceNode.attribute("name") == "deviceNumber")
1107
+	{
1108
+		configAuto = deviceNode.attribute("value");
1109
+	}
1110
+	else if(deviceNode.attribute("name") == "port")
1111
+	{
1112
+		configPort = deviceNode.attribute("value");
1113
+	}
993
 }
1114
 }
1115
+deviceID = autoSelect ? configAuto : configPort;
1116
+channelOfInterest = index.row();
994
 
1117
 
995
 @ It must be possible to perform calibration operations with the hardware not
1118
 @ It must be possible to perform calibration operations with the hardware not
996
 connected. As such, the device should only be opened on request. Methods for
1119
 connected. As such, the device should only be opened on request. Methods for
999
 @<DataqSdkDeviceConfWidget implementation@>=
1122
 @<DataqSdkDeviceConfWidget implementation@>=
1000
 void DataqSdkChannelConfWidget::startCalibration()
1123
 void DataqSdkChannelConfWidget::startCalibration()
1001
 {
1124
 {
1002
-
1125
+	startButton->setEnabled(false);
1126
+	stopButton->setEnabled(true);
1127
+	resetButton->setEnabled(true);
1128
+	calibrationDevice = new DataqSdkDevice(deviceID);
1129
+	Channel *channel;
1130
+	for(int i = 0; i <= channelOfInterest; i++)
1131
+	{
1132
+		channel = calibrationDevice->newChannel(Units::Unitless);
1133
+	}
1134
+	connect(channel, SIGNAL(newData(Measurement)), this, SLOT(updateInput(Measurement)));
1135
+	connect(channel, SIGNAL(newData(Measurement)), calibrator, SLOT(newMeasurement(Measurement)));
1136
+	connect(calibrator, SIGNAL(newData(Measurement)), this, SLOT(updateOutput(Measurement)));
1137
+	calibrationDevice->setClockRate(6.0 / (1.0 + channelOfInterest));
1138
+	calibrationDevice->start();
1003
 }
1139
 }
1004
 
1140
 
1005
 void DataqSdkChannelConfWidget::stopCalibration()
1141
 void DataqSdkChannelConfWidget::stopCalibration()
1006
 {
1142
 {
1007
-
1143
+	startButton->setEnabled(true);
1144
+	stopButton->setEnabled(false);
1145
+	resetButton->setEnabled(false);
1146
+	calibrationDevice->deleteLater();
1147
+	@<Reset DATAQ SDK channel calibration aggregates@>@;
1008
 }
1148
 }
1009
 
1149
 
1010
 @ When collecting calibration data it is useful to have a few types of
1150
 @ When collecting calibration data it is useful to have a few types of
1018
 @<DataqSdkDeviceConfWidget implementation@>=
1158
 @<DataqSdkDeviceConfWidget implementation@>=
1019
 void DataqSdkChannelConfWidget::resetCalibration()
1159
 void DataqSdkChannelConfWidget::resetCalibration()
1020
 {
1160
 {
1161
+	@<Reset DATAQ SDK channel calibration aggregates@>@;
1162
+}
1163
+
1164
+@ When calibration is stopped or reset, aggregate statistics are set to
1165
+their initial values;
1166
+
1167
+@<Reset DATAQ SDK channel calibration aggregates@>=
1168
+rmCount = 0;
1169
+cmCount = 0;
1170
+rmin = std::numeric_limits<double>::max();
1171
+rmax = std::numeric_limits<double>::min();
1172
+rmean = 0;
1173
+cmin = std::numeric_limits<double>::max();
1174
+cmax = std::numeric_limits<double>::min();
1175
+cmean = 0;
1021
 
1176
 
1177
+@ Two methods are responsible for updating line edits with current and
1178
+aggregate data when calibrating a channel. One handles raw measurements from
1179
+the channel and the other handles output from the |LinearCalibrator|.
1180
+
1181
+@<DataqSdkDeviceConfWidget implementation@>=
1182
+void DataqSdkChannelConfWidget::updateInput(Measurement measure)
1183
+{
1184
+	double nv = measure.temperature();
1185
+	currentMeasurement->setText(QString("%1").arg(nv));
1186
+	rmin = qMin(nv, rmin);
1187
+	minimumMeasurement->setText(QString("%1").arg(rmin));
1188
+	rmax = qMax(nv, rmax);
1189
+	maximumMeasurement->setText(QString("%1").arg(rmax));
1190
+	rmean = ((rmean * rmCount) + nv) / (rmCount + 1);
1191
+	rmCount++;
1192
+	averageMeasurement->setText(QString("%1").arg(rmean));
1193
+}
1194
+
1195
+void DataqSdkChannelConfWidget::updateOutput(Measurement measure)
1196
+{
1197
+	double nv = measure.temperature();
1198
+	currentMapped->setText(QString("%1").arg(nv));
1199
+	cmin = qMin(nv, cmin);
1200
+	minimumMapped->setText(QString("%1").arg(cmin));
1201
+	cmax = qMax(nv, cmax);
1202
+	maximumMapped->setText(QString("%1").arg(cmax));
1203
+	cmean = ((cmean * cmCount) + nv) / (cmCount + 1);
1204
+	cmCount++;
1205
+	averageMapped->setText(QString("%1").arg(cmean));
1022
 }
1206
 }
1023
 
1207
 
1024
 @ Column name is handled as usual.
1208
 @ Column name is handled as usual.

Loading…
Cancel
Save