[chronojump] forceSensor: can capture using absolute values or inverted values



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]