[chronojump] forceSensor: can capture using absolute values or inverted values
- From: Xavier de Blas <xaviblas src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [chronojump] forceSensor: can capture using absolute values or inverted values
- Date: Fri, 6 Sep 2019 13:06:07 +0000 (UTC)
commit 4fbb8b8e1767161498a0bf7ec935cf93b1cd247c
Author: Xavier de Blas <xaviblas gmail com>
Date: Thu Sep 5 09:32:33 2019 +0200
forceSensor: can capture using absolute values or inverted values
glade/app1.glade | 91 ++++++++++++++++++++++++++++++---------
r-scripts/maximumIsometricForce.R | 22 ++++++----
src/forceSensor.cs | 30 ++++++++++---
src/gui/forceSensor.cs | 44 ++++++++++++++-----
src/gui/forceSensorAnalyze.cs | 2 +-
5 files changed, 144 insertions(+), 45 deletions(-)
---
diff --git a/glade/app1.glade b/glade/app1.glade
index c2eaf9dc..d19cb2cf 100644
--- a/glade/app1.glade
+++ b/glade/app1.glade
@@ -5854,8 +5854,8 @@ EncoderInertialCapture</property>
</child>
</widget>
<packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
@@ -5869,7 +5869,7 @@ EncoderInertialCapture</property>
<signal name="clicked"
handler="on_button_auto_start_clicked" swapped="no"/>
</widget>
<packing>
- <property name="expand">False</property>
+ <property name="expand">True</property>
<property name="fill">False</property>
<property name="pack_type">end</property>
<property name="position">3</property>
@@ -5877,8 +5877,8 @@ EncoderInertialCapture</property>
</child>
</widget>
<packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
@@ -6592,7 +6592,7 @@ EncoderInertialCapture</property>
<widget class="GtkHBox"
id="hbox_force_capture_buttons">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="spacing">100</property>
+ <property name="spacing">12</property>
<child>
<widget class="GtkHBox" id="hbox_force_sensor">
<property name="visible">True</property>
@@ -6702,13 +6702,18 @@ EncoderInertialCapture</property>
</packing>
</child>
<child>
+ <widget class="GtkHBox" id="hbox236">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">12</property>
+ <child>
<widget class="GtkButton"
id="button_force_sensor_capture_load">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="clicked"
handler="on_button_force_sensor_load_clicked" swapped="no"/>
<child>
- <widget class="GtkHBox" id="hbox236">
+ <widget class="GtkHBox" id="hbox329">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
@@ -6742,6 +6747,27 @@ EncoderInertialCapture</property>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkButton"
id="button_force_sensor_capture_recalculate">
+ <property name="label"
translatable="yes">Recalculate</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <signal name="clicked"
handler="on_button_force_sensor_capture_recalculate_clicked" swapped="no"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
@@ -7104,8 +7130,8 @@ EncoderInertialCapture</property>
</child>
</widget>
<packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
@@ -7482,6 +7508,7 @@ EncoderInertialCapture</property>
</child>
<child>
<widget class="GtkButton"
id="button_force_sensor_adjust">
+ <property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="clicked"
handler="on_button_force_sensor_adjust_clicked" swapped="no"/>
@@ -7525,7 +7552,6 @@ EncoderInertialCapture</property>
</child>
<child>
<widget class="GtkHBox"
id="hbox_race_analyzer_device">
- <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">4</property>
<child>
@@ -8969,6 +8995,20 @@ EncoderInertialCapture</property>
<property name="can_focus">False</property>
<property name="spacing">20</property>
<child>
+ <widget class="GtkComboBox"
id="combo_force_sensor_capture_options">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="items"
translatable="yes">Standard capture
+Absolute values
+Inverted values</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
<widget class="GtkHBox"
id="hbox_force_sensor_laterality">
<property name="visible">True</property>
<property name="can_focus">False</property>
@@ -9134,9 +9174,9 @@ EncoderInertialCapture</property>
</child>
</widget>
<packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
</packing>
</child>
<child>
@@ -9165,21 +9205,18 @@ EncoderInertialCapture</property>
</child>
</widget>
<packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
</packing>
</child>
</widget>
<packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
- <child>
- <placeholder/>
- </child>
</widget>
<packing>
<property name="position">4</property>
@@ -21730,6 +21767,12 @@ Concentric</property>
<child>
<placeholder/>
</child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
</widget>
<packing>
<property name="expand">False</property>
@@ -30594,6 +30637,12 @@ then click this button.</property>
<child>
<placeholder/>
</child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
</widget>
<packing>
<property name="expand">False</property>
diff --git a/r-scripts/maximumIsometricForce.R b/r-scripts/maximumIsometricForce.R
index 600cd21b..6a2fe531 100644
--- a/r-scripts/maximumIsometricForce.R
+++ b/r-scripts/maximumIsometricForce.R
@@ -46,8 +46,9 @@ assignOptions <- function(options)
drawRfdOptions = drawRfdOptions,
drawImpulseOptions = options[16],
testLength = as.numeric(options[17]),
- title = options[18],
- scriptsPath = options[19]
+ captureOptions = options[18],
+ title = options[19],
+ scriptsPath = options[20]
))
}
@@ -87,12 +88,17 @@ getForceModel <- function(time, force, startTime, # startTime is the instant whe
return(list(fmax = fmax, K = K, error =sum(abs(residuals(model)))))
}
-getDynamicsFromLoadCellFile <- function(inputFile, averageLength = 0.1, percentChange = 5, bestFit = TRUE,
testLength = -1)
+getDynamicsFromLoadCellFile <- function(captureOptions, inputFile, averageLength = 0.1, percentChange = 5,
bestFit = TRUE, testLength = -1)
{
originalTest = read.csv(inputFile, header = F, dec = op$decimalChar, sep = ";", skip = 2)
colnames(originalTest) <- c("time", "force")
originalTest$time = as.numeric(originalTest$time / 1000000) # Time is converted from microseconds
to seconds
-
+
+ if(captureOptions == "ABS")
+ originalTest$force = abs(originalTest$force)
+ else if(captureOptions == "INVERTED")
+ originalTest$force = -1 * originalTest$force
+
#Instantaneous RFD
rfd = getRFD(originalTest)
@@ -195,7 +201,7 @@ getDynamicsFromLoadCellFile <- function(inputFile, averageLength = 0.1, percentC
}
drawDynamicsFromLoadCell <- function(
- dynamics, vlineT0=T, vline50fmax.raw=F, vline50fmax.fitted=F,
+ dynamics, captureOptions, vlineT0=T, vline50fmax.raw=F, vline50fmax.fitted=F,
hline50fmax.raw=F, hline50fmax.fitted=F,
rfdDrawingOptions, xlimits = NA)
{
@@ -619,7 +625,7 @@ getDynamicsFromLoadCellFolder <- function(folderName, resultFileName, export2Pdf
for(i in 1:nFiles)
{
- dynamics = getDynamicsFromLoadCellFile(paste(folderName,originalFiles[i], sep = ""))
+ dynamics = getDynamicsFromLoadCellFile(op$captureOptions, paste(folderName,originalFiles[i],
sep = ""))
results[i, "fileName"] = dynamics$nameOfFile
results[i, "fmax.fitted"] = dynamics$fmax.fitted
@@ -768,8 +774,8 @@ readImpulseOptions <- function(optionsStr)
prepareGraph(op$os, pngFile, op$graphWidth, op$graphHeight)
-dynamics = getDynamicsFromLoadCellFile(dataFile, op$averageLength, op$percentChange, bestFit = TRUE,
testLength = -1)
-drawDynamicsFromLoadCell(dynamics, op$vlineT0, op$vline50fmax.raw, op$vline50fmax.fitted,
op$hline50fmax.raw, op$hline50fmax.fitted,
+dynamics = getDynamicsFromLoadCellFile(op$captureOptions, dataFile, op$averageLength, op$percentChange,
bestFit = TRUE, testLength = -1)
+drawDynamicsFromLoadCell(dynamics, op$captureOptions, op$vlineT0, op$vline50fmax.raw, op$vline50fmax.fitted,
op$hline50fmax.raw, op$hline50fmax.fitted,
op$drawRfdOptions)
# op$drawRfdOptions, xlimits = c(0.5, 1.5))
endGraph()
diff --git a/src/forceSensor.cs b/src/forceSensor.cs
index a00b1d0c..7393bf6e 100644
--- a/src/forceSensor.cs
+++ b/src/forceSensor.cs
@@ -23,6 +23,21 @@ using System.IO; //for detect OS
using System.Collections.Generic; //List<T>
using Mono.Unix;
+public class ForceSensor
+{
+ public enum CaptureOptions { NORMAL, ABS, INVERTED }
+
+ public static double ForceWithFlags(double force, CaptureOptions fsco)
+ {
+ if(fsco == CaptureOptions.ABS)
+ return Math.Abs(force);
+ if(fsco == CaptureOptions.INVERTED)
+ return -1 * force;
+
+ return force;
+ }
+}
+
public class ForceSensorExercise
{
private int uniqueID;
@@ -607,6 +622,7 @@ public class ForceSensorImpulse : ForceSensorRFD
public class ForceSensorGraph
{
+ ForceSensor.CaptureOptions fsco;
List<ForceSensorRFD> rfdList;
ForceSensorImpulse impulse;
double averageLength;
@@ -619,8 +635,10 @@ public class ForceSensorGraph
int testLength;
string title;
- public ForceSensorGraph(List<ForceSensorRFD> rfdList, ForceSensorImpulse impulse, int testLength,
string title)
+ public ForceSensorGraph(ForceSensor.CaptureOptions fsco, List<ForceSensorRFD> rfdList,
+ ForceSensorImpulse impulse, int testLength, string title)
{
+ this.fsco = fsco;
this.rfdList = rfdList;
this.impulse = impulse;
this.testLength = testLength;
@@ -678,6 +696,7 @@ public class ForceSensorGraph
scriptOptions +=
"\n#testLength\n" + testLength.ToString() + "\n" +
+ "#captureOptions\n" + fsco.ToString() + "\n" +
"#title\n" + title + "\n" +
"#scriptsPath\n" + UtilEncoder.GetScriptsPath() + "\n";
@@ -714,12 +733,12 @@ public class ForceSensorAnalyzeInstant
private int graphWidth;
private int graphHeight;
- public ForceSensorAnalyzeInstant(string file, int graphWidth, int graphHeight, double start, double
end)
+ public ForceSensorAnalyzeInstant(string file, int graphWidth, int graphHeight, double start, double
end, ForceSensor.CaptureOptions fsco)
{
this.graphWidth = graphWidth;
this.graphHeight = graphHeight;
- readFile(file, start, end);
+ readFile(file, start, end, fsco);
//on zoom adjust width
if(start >= 0 || end >= 0)
@@ -733,7 +752,7 @@ public class ForceSensorAnalyzeInstant
fscAIPoints.Redo();
}
- private void readFile(string file, double start, double end)
+ private void readFile(string file, double start, double end, ForceSensor.CaptureOptions fsco)
{
fscAIPoints = new ForceSensorCapturePoints(graphWidth, graphHeight);
@@ -776,6 +795,7 @@ public class ForceSensorAnalyzeInstant
int time = Convert.ToInt32(timeD);
double force = Convert.ToDouble(strFull[1]);
+ force = ForceSensor.ForceWithFlags(force, fsco);
fscAIPoints.Add(time, force);
fscAIPoints.NumCaptured ++;
@@ -1030,7 +1050,7 @@ public class ForceSensorAnalyzeInstant
}
-//we need this class because we started using foresensor without database (only text files)
+//we need this class because we started using forcesensor without database (only text files)
public class ForceSensorLoadTryToAssignPersonAndMore
{
private string filename; //filename comes without extension
diff --git a/src/gui/forceSensor.cs b/src/gui/forceSensor.cs
index 3b31fdab..afa605fa 100644
--- a/src/gui/forceSensor.cs
+++ b/src/gui/forceSensor.cs
@@ -69,6 +69,7 @@ public partial class ChronoJumpWindow
[Widget] Gtk.HBox hbox_force_capture_buttons;
[Widget] Gtk.HBox hbox_combo_force_sensor_exercise;
[Widget] Gtk.ComboBox combo_force_sensor_exercise;
+ [Widget] Gtk.ComboBox combo_force_sensor_capture_options;
[Widget] Gtk.RadioButton radio_force_sensor_laterality_both;
[Widget] Gtk.RadioButton radio_force_sensor_laterality_l;
[Widget] Gtk.RadioButton radio_force_sensor_laterality_r;
@@ -128,7 +129,6 @@ public partial class ChronoJumpWindow
bool forceSensorBinaryCapture;
int forceSensorTopRectangleAtOperationStart; //operation can be capture, load
-
Gdk.GC pen_black_force_capture;
Gdk.GC pen_red_force_capture;
Gdk.GC pen_white_force_capture;
@@ -149,6 +149,7 @@ public partial class ChronoJumpWindow
{
notebook_force_sensor_analyze.CurrentPage = 1; //start on 1: force_general_analysis
createForceExerciseCombo();
+ combo_force_sensor_capture_options.Active = 0;
createForceAnalyzeCombos();
setRFDValues();
setImpulseValue();
@@ -752,6 +753,8 @@ public partial class ChronoJumpWindow
getCaptureComment() + //includes "_" if it's no empty
UtilDate.ToFile(DateTime.Now);
+ ForceSensor.CaptureOptions forceSensorCaptureOption = getForceSensorCaptureOptions();
+
//fileName to save the csv
string fileName = Util.GetForceSensorSessionDir(currentSession.UniqueID) +
Path.DirectorySeparatorChar + fileNamePre + ".csv";
@@ -813,14 +816,19 @@ public partial class ChronoJumpWindow
time -= firstTime;
LogB.Information(string.Format("time: {0}, force: {1}", time, force));
- writer.WriteLine(time.ToString() + ";" + force.ToString());
+ //forceWithFlags have abs or inverted
+ double forceWithFlags = ForceSensor.ForceWithFlags(force, forceSensorCaptureOption);
+ if(forceSensorCaptureOption != ForceSensor.CaptureOptions.NORMAL)
+ LogB.Information(string.Format("with abs or inverted flag: time: {0}, force:
{1}", time, forceWithFlags));
+
+ writer.WriteLine(time.ToString() + ";" + force.ToString()); //on file force is stored
without flags
forceSensorValues.TimeLast = time;
- forceSensorValues.ForceLast = force;
+ forceSensorValues.ForceLast = forceWithFlags;
- forceSensorValues.SetMaxMinIfNeeded(force, time);
+ forceSensorValues.SetMaxMinIfNeeded(forceWithFlags, time);
- fscPoints.Add(time, force);
+ fscPoints.Add(time, forceWithFlags);
fscPoints.NumCaptured ++;
if(fscPoints.OutsideGraph())
{
@@ -1231,6 +1239,10 @@ LogB.Information(" re R ");
lastForceSensorFullPath = filechooser.Filename; //used on recalculate
+ //on load, standard capture will be used.
+ //when database is working the here the gui of ForceSensor.CaptureOptions will
change, and graph will be done accordingly
+ combo_force_sensor_capture_options.Active = 0;
+
forceSensorCopyTempAndDoGraphs();
//if drawingarea has still not shown, don't paint graph because GC screen is not
defined
@@ -1281,7 +1293,7 @@ LogB.Information(" re R ");
else
title = Util.RemoveChar(title, '_');
- ForceSensorGraph fsg = new ForceSensorGraph(rfdList, impulse, duration, title);
+ ForceSensorGraph fsg = new ForceSensorGraph(getForceSensorCaptureOptions(), rfdList, impulse,
duration, title);
int imageWidth = UtilGtk.WidgetWidth(viewport_force_sensor_graph);
int imageHeight = UtilGtk.WidgetHeight(viewport_force_sensor_graph);
@@ -1314,10 +1326,10 @@ LogB.Information(" re R ");
void forceSensorDoSignalGraph()
{
- forceSensorDoSignalGraphReadFile();
+ forceSensorDoSignalGraphReadFile(getForceSensorCaptureOptions());
forceSensorDoSignalGraphPlot();
}
- void forceSensorDoSignalGraphReadFile()
+ void forceSensorDoSignalGraphReadFile(ForceSensor.CaptureOptions fsco)
{
fscPoints = new ForceSensorCapturePoints(
force_capture_drawingarea.Allocation.Width,
@@ -1348,6 +1360,7 @@ LogB.Information(" re R ");
{
int time = Convert.ToInt32(strFull[0]);
double force = Convert.ToDouble(strFull[1]);
+ force = ForceSensor.ForceWithFlags(force, fsco);
fscPoints.Add(time, force);
fscPoints.NumCaptured ++;
@@ -1945,7 +1958,18 @@ LogB.Information(" re R ");
// -------------------------------- end of exercise stuff --------------------
- // -------------------------------- laterality and comment stuff -------------
+ // -------------------------------- options, laterality and comment stuff -------------
+
+ private ForceSensor.CaptureOptions getForceSensorCaptureOptions()
+ {
+ string option = UtilGtk.ComboGetActive(combo_force_sensor_capture_options);
+ if(option == Catalog.GetString("Absolute values"))
+ return ForceSensor.CaptureOptions.ABS;
+ else if(option == Catalog.GetString("Inverted values"))
+ return ForceSensor.CaptureOptions.INVERTED;
+ else
+ return ForceSensor.CaptureOptions.NORMAL;
+ }
private string getLaterality()
{
@@ -1975,7 +1999,7 @@ LogB.Information(" re R ");
return s;
}
- // -------------------------------- end of laterality and comment stuff ------
+ // -------------------------------- end of options, laterality and comment stuff ------
// ------------------------------------------------ slides stuff for presentations
diff --git a/src/gui/forceSensorAnalyze.cs b/src/gui/forceSensorAnalyze.cs
index 86dc68ae..25ad604c 100644
--- a/src/gui/forceSensorAnalyze.cs
+++ b/src/gui/forceSensorAnalyze.cs
@@ -549,7 +549,7 @@ public partial class ChronoJumpWindow
lastForceSensorFullPath,
force_sensor_ai_drawingarea.Allocation.Width,
force_sensor_ai_drawingarea.Allocation.Height,
- zoomA, zoomB);
+ zoomA, zoomB, getForceSensorCaptureOptions());
/*
* position the hscales on the left to avoid loading a csv
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]