[chronojump] Force sensor graph working
- From: Xavier de Blas <xaviblas src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [chronojump] Force sensor graph working
- Date: Mon, 24 Apr 2017 22:19:32 +0000 (UTC)
commit 2b6daf8a2bfef9f265e7fa18591d31480fffcfe2
Author: Xavier de Blas <xaviblas gmail com>
Date: Tue Apr 25 00:19:03 2017 +0200
Force sensor graph working
glade/app1.glade | 60 +++++++++++++++++++-
r-scripts/maximumIsometricForce.R | 59 ++++++++++---------
src/forceSensor.cs | 112 +++++++++++++++++++++++++++++++++++++
src/gui/chronojump.cs | 6 ++
src/gui/forceSensor.cs | 58 ++++++++++++++++---
src/utilEncoder.cs | 2 +-
6 files changed, 256 insertions(+), 41 deletions(-)
---
diff --git a/glade/app1.glade b/glade/app1.glade
index 47994b2..49b1529 100644
--- a/glade/app1.glade
+++ b/glade/app1.glade
@@ -1224,6 +1224,12 @@
<placeholder/>
</child>
<child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
<widget class="GtkLabel"
id="label_start_selector_jumps">
<property name="visible">True</property>
<property name="can_focus">False</property>
@@ -4085,6 +4091,21 @@ EncoderInertialCapture</property>
</packing>
</child>
<child>
+ <widget class="GtkButton"
id="button_force_sensor_graph">
+ <property name="label"
translatable="yes">Graph</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_graph_clicked" swapped="no"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="padding">20</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
<widget class="GtkButton"
id="button_force_sensor_data_folder">
<property name="label" translatable="yes">Open
data folder</property>
<property name="visible">True</property>
@@ -4096,7 +4117,7 @@ EncoderInertialCapture</property>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="padding">20</property>
- <property name="position">3</property>
+ <property name="position">4</property>
</packing>
</child>
</widget>
@@ -4416,7 +4437,7 @@ EncoderInertialCapture</property>
<property name="can_focus">False</property>
<property name="top_padding">8</property>
<child>
- <widget class="GtkHBox" id="hbox75">
+ <widget class="GtkHBox"
id="hbox_chronopics_and_threshold">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">8</property>
@@ -10411,9 +10432,36 @@ after time</property>
</child>
</widget>
<packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkScrolledWindow"
id="scrolledwindow5">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property
name="hscrollbar_policy">automatic</property>
+ <property
name="vscrollbar_policy">automatic</property>
+ <child>
+ <widget class="GtkViewport"
id="viewport_force_sensor_graph">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <widget class="GtkImage"
id="image_force_sensor_graph">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property
name="stock">gtk-missing-image</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
<property name="expand">True</property>
<property name="fill">True</property>
- <property name="position">1</property>
+ <property name="position">2</property>
</packing>
</child>
</widget>
@@ -20242,6 +20290,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 45794c9..86bd313 100644
--- a/r-scripts/maximumIsometricForce.R
+++ b/r-scripts/maximumIsometricForce.R
@@ -37,22 +37,23 @@ endGraph <- function()
assignOptions <- function(options)
{
- drawRfdOptions = rep(NA, length(options) - 10)
- for(n in 11:length(options))
+ drawRfdOptions = rep(NA, length(options) - 11)
+ for(n in 12:length(options))
{
- drawRfdOptions[n-10] = options[n]
+ drawRfdOptions[n-11] = options[n]
}
return(list(
- os = options[1],
- graphWidth = as.numeric(options[2]),
- graphHeight = as.numeric(options[3]),
- averageLength = as.numeric(options[4]),
- percentChange = as.numeric(options[5]),
- vlineT0 = as.numeric(options[6]),
- vline50fmax.raw = as.numeric(options[7]),
- vline50fmax.fitted = as.numeric(options[8]),
- hline50fmax.raw = as.numeric(options[9]),
- hline50fmax.fitted = as.numeric(options[10]),
+ os = options[1],
+ decimalChar = options[2],
+ graphWidth = as.numeric(options[3]),
+ graphHeight = as.numeric(options[4]),
+ averageLength = as.numeric(options[5]),
+ percentChange = as.numeric(options[6]),
+ vlineT0 = options[7],
+ vline50fmax.raw = options[8],
+ vline50fmax.fitted = options[9],
+ hline50fmax.raw = options[10],
+ hline50fmax.fitted = options[11],
drawRfdOptions = drawRfdOptions
))
}
@@ -91,7 +92,7 @@ getForceModel <- function(time, force, startTime, # startTime is the instant whe
getDynamicsFromLoadCellFile <- function(inputFile, averageLength = 0.1, percentChange = 5)
{
- originalTest = read.csv(inputFile, header = F, dec = ".", sep = ";", skip = 2)
+ originalTest = read.csv(inputFile, header = F, dec = op$decimalChar, sep = ";", skip = 2)
colnames(originalTest) <- c("time", "force")
originalTest$time = as.numeric(originalTest$time)
@@ -263,26 +264,28 @@ drawDynamicsFromLoadCell <- function(
RFD = NULL
sample2 = NA
+ pointForce1 = NA
pointForce2 = NA
+ color = ""
- if(options$rfdFunction == "fitted")
+ if(options$rfdFunction == "FITTED")
{
color = "blue"
- } else if(options$rfdFunction == "raw")
+ } else if(options$rfdFunction == "RAW")
{
color = "black"
}
- if(options$type == "instant") # TODO: || percent ...(all except AVG)
+ if(options$type == "INSTANTANEOUS") # TODO: || percent ...(all except AVG)
{
- if (options$rfdFunction == "fitted")
+ if (options$rfdFunction == "FITTED")
{
#Slope of the line
RFD = dynamics$fmax.fitted * dynamics$k.fitted * exp(-dynamics$k.fitted *
options$start)
#Y coordinate of a point of the line
pointForce1 = dynamics$fmax.fitted*(1 - exp(-dynamics$k.fitted *
options$start)) + dynamics$initf
- } else if(options$rfdFunction == "raw")
+ } else if(options$rfdFunction == "RAW")
{
color = "black"
sample1 = which.min(abs(dynamics$time - dynamics$startTime - options$start))
@@ -293,15 +296,15 @@ drawDynamicsFromLoadCell <- function(
#Y coordinate of a point of the line
pointForce1 = dynamics$f.raw[sample1]
}
- } else if(options$type == "avg")
+ } else if(options$type == "AVERAGE")
{
- if (options$rfdFunction == "fitted")
+ if (options$rfdFunction == "FITTED")
{
#Slope of the line
RFD = dynamics$fmax.fitted*(exp( -dynamics$k.fitted * options$start) - exp(
-dynamics$k.fitted * options$end)) / (options$end - options$start)
#Y coordinate of a point of the line
pointForce1 = dynamics$fmax.fitted*(1 - exp( -dynamics$k.fitted *
options$start)) + dynamics$initf
- } else if(options$rfdFunction == "raw")
+ } else if(options$rfdFunction == "RAW")
{
sample1 = which.min(abs(dynamics$time - dynamics$startTime - options$start))
sample2 = which.min(abs(dynamics$time - dynamics$startTime - options$end))
@@ -313,10 +316,10 @@ drawDynamicsFromLoadCell <- function(
pointForce1 = dynamics$f.raw[sample1]
}
- } else if(options$type == "%fmax")
+ } else if(options$type == "PERCENT_F_MAX")
{
- if (options$rfdFunction == "fitted")
+ if (options$rfdFunction == "FITTED")
{
#Force that is the % of the raw fmax
fpfmax = dynamics$fmax.raw*options$start/100
@@ -330,7 +333,7 @@ drawDynamicsFromLoadCell <- function(
#Y coordinate of a point of the line
pointForce1 = dynamics$fmax.fitted*(1 - exp(-dynamics$k.fitted *
options$start)) + dynamics$initf
- } else if(options$rfdFunction == "raw")
+ } else if(options$rfdFunction == "RAW")
{
#Calculing at which sample force is equal to the percent of fmax specified
in options$start
sample1 = which.min(abs(dynamics$f.raw -
dynamics$fmax.raw*options$start/100))
@@ -344,13 +347,13 @@ drawDynamicsFromLoadCell <- function(
#Y coordinate of a point of the line
pointForce1 = dynamics$f.raw[sample1]
}
- } else if(options$type == "rfdmax")
+ } else if(options$type == "RFD_MAX")
{
- if (options$rfdFunction == "fitted")
+ if (options$rfdFunction == "FITTED")
{
#max is always in the initial point.
- } else if(options$rfdFunction == "raw")
+ } else if(options$rfdFunction == "RAW")
{
#Calculing the sample at which the rfd is max
sample1 = which.max(dynamics$rfd)
diff --git a/src/forceSensor.cs b/src/forceSensor.cs
index a5b7b64..8d404be 100644
--- a/src/forceSensor.cs
+++ b/src/forceSensor.cs
@@ -140,6 +140,11 @@ public class ForceSensorRFD
num2.ToString();
}
+ public string ToR()
+ {
+ return function.ToString() + ";" + type.ToString() + ";" + num1.ToString() + ";" +
num2.ToString();
+ }
+
public static string Function_RAW_name
{
get { return function_RAW_name; }
@@ -167,6 +172,113 @@ public class ForceSensorRFD
}
}
+public class ForceSensorGraph
+{
+ List<ForceSensorRFD> rfdList;
+ double averageLength;
+ double percentChange;
+ bool vlineT0;
+ bool vline50fmax_raw;
+ bool vline50fmax_fitted;
+ bool hline50fmax_raw;
+ bool hline50fmax_fitted;
+
+ public ForceSensorGraph(List<ForceSensorRFD> rfdList)
+ {
+ this.rfdList = rfdList;
+
+ averageLength = 0.1;
+ percentChange = 5;
+ vlineT0 = false;
+ vline50fmax_raw = false;
+ vline50fmax_fitted = false;
+ hline50fmax_raw = false;
+ hline50fmax_fitted = false;
+ }
+
+ public bool CallR(int graphWidth, int graphHeight)
+ {
+ string executable = UtilEncoder.RProcessBinURL();
+ List<string> parameters = new List<string>();
+
+ //A) mifcript
+ string mifScript = UtilEncoder.GetmifScript();
+ if(UtilAll.IsWindows())
+ mifScript = mifScript.Replace("\\","/");
+
+ parameters.Insert(0, "\"" + mifScript + "\"");
+
+ //B) tempPath
+ string tempPath = Path.GetTempPath();
+ if(UtilAll.IsWindows())
+ tempPath = tempPath.Replace("\\","/");
+
+ parameters.Insert(1, "\"" + tempPath + "\"");
+
+ //C) writeOptions
+ writeOptionsFile(graphWidth, graphHeight);
+
+ LogB.Information("\nCalling mif R file ----->");
+
+ //D) call process
+ //ExecuteProcess.run (executable, parameters);
+ ExecuteProcess.Result execute_result = ExecuteProcess.run (executable, parameters);
+ //LogB.Information("Result = " + execute_result.stdout);
+
+ LogB.Information("\n<------ Done calling mif R file.");
+ return execute_result.success;
+ }
+
+ private void writeOptionsFile(int graphWidth, int graphHeight)
+ {
+ string scriptsPath = UtilEncoder.GetSprintPath();
+ if(UtilAll.IsWindows())
+ scriptsPath = scriptsPath.Replace("\\","/");
+
+ System.Globalization.NumberFormatInfo localeInfo = new
System.Globalization.NumberFormatInfo();
+ localeInfo = System.Globalization.NumberFormatInfo.CurrentInfo;
+
+ string scriptOptions =
+ "#os\n" + UtilEncoder.OperatingSystemForRGraphs() + "\n" +
+ "#decimalChar\n" + localeInfo.NumberDecimalSeparator + "\n" +
+ "#graphWidth\n" + graphWidth.ToString() + "\n" +
+ "#graphHeight\n" + graphHeight.ToString() + "\n" +
+ "#averageLength\n" + Util.ConvertToPoint(averageLength) + "\n" +
+ "#percentChange\n" + Util.ConvertToPoint(percentChange) + "\n" +
+ "#vlineT0\n" + Util.BoolToRBool(vlineT0) + "\n" +
+ "#vline50fmax.raw\n" + Util.BoolToRBool(vline50fmax_raw) + "\n" +
+ "#vline50fmax.fitted\n" + Util.BoolToRBool(vline50fmax_fitted) + "\n" +
+ "#hline50fmax.raw\n" + Util.BoolToRBool(hline50fmax_raw) + "\n" +
+ "#hline50fmax.fitted\n" + Util.BoolToRBool(hline50fmax_fitted) + "\n" +
+ "#RFDs";
+
+ foreach(ForceSensorRFD rfd in rfdList)
+ if(rfd.active)
+ scriptOptions += "\n" + rfd.ToR();
+
+ TextWriter writer = File.CreateText(Path.GetTempPath() + "Roptions.txt");
+ writer.Write(scriptOptions);
+ writer.Flush();
+ writer.Close();
+ ((IDisposable)writer).Dispose();
+ }
+
+ public static string GetDataDir(int sessionID)
+ {
+ System.IO.DirectoryInfo folderSession =
+ new System.IO.DirectoryInfo(Util.GetForceSensorSessionDir(sessionID));
+ System.IO.DirectoryInfo folderGeneric =
+ new System.IO.DirectoryInfo(Util.GetForceSensorDir());
+
+ if(folderSession.Exists)
+ return Util.GetForceSensorSessionDir(sessionID);
+ else if(folderGeneric.Exists)
+ return Util.GetForceSensorDir();
+ else
+ return "";
+ }
+}
+
/*
public class ForceSensor
{
diff --git a/src/gui/chronojump.cs b/src/gui/chronojump.cs
index 742252e..a896981 100644
--- a/src/gui/chronojump.cs
+++ b/src/gui/chronojump.cs
@@ -270,6 +270,7 @@ public partial class ChronoJumpWindow
[Widget] Gtk.Box vbox_execute_test;
[Widget] Gtk.Button button_execute_test;
+ [Widget] Gtk.HBox hbox_chronopics_and_threshold;
[Widget] Gtk.Viewport viewport_chronopics;
//[Widget] Gtk.Label label_chronopic_encoder;
//[Widget] Gtk.Image image_chronopic_encoder_no;
@@ -780,6 +781,7 @@ public partial class ChronoJumpWindow
notebooks_change(Constants.Menuitem_modes.FORCESENSOR);
//on_extra_window_force_sensor_test_changed(obj, args);
hbox_results_legend.Visible = false;
+ notebook_capture_graph_table.CurrentPage = 1; //"Show table"
}
public void on_radio_menuitem_mode_rt_toggled (object obj, EventArgs args)
@@ -2808,6 +2810,7 @@ public partial class ChronoJumpWindow
hbox_other.Visible = false;
vbox_last_test_buttons.Sensitive = false;
+ hbox_chronopics_and_threshold.Visible = true;
if(m == Constants.Menuitem_modes.JUMPSSIMPLE || m == Constants.Menuitem_modes.JUMPSREACTIVE)
{
@@ -2997,6 +3000,9 @@ public partial class ChronoJumpWindow
//notebook_capture_analyze.ShowTabs = false; //only capture tab is shown (only valid
for "OTHER" tests)
hbox_contacts_sup_capture_analyze_two_buttons.Visible = false;
//notebook_capture_analyze.GetNthPage(2).Hide(); //hide jumpsProfile on other tests
+ hbox_chronopics_and_threshold.Visible = false;
+ hbox_results_legend.Visible = false;
+ notebook_capture_graph_table.CurrentPage = 1; //"Show table"
}
else if(m == Constants.Menuitem_modes.RT)
{
diff --git a/src/gui/forceSensor.cs b/src/gui/forceSensor.cs
index 510896c..0398e72 100644
--- a/src/gui/forceSensor.cs
+++ b/src/gui/forceSensor.cs
@@ -35,6 +35,8 @@ public partial class ChronoJumpWindow
[Widget] Gtk.Label label_force_sensor_value;
[Widget] Gtk.Label label_force_sensor_value_min;
[Widget] Gtk.VScale vscale_force_sensor;
+ [Widget] Gtk.Viewport viewport_force_sensor_graph;
+ [Widget] Gtk.Image image_force_sensor_graph;
CjComboForceSensorPorts comboForceSensorPorts;
@@ -227,17 +229,55 @@ public partial class ChronoJumpWindow
return true;
}
+ private void on_button_force_sensor_graph_clicked (object o, EventArgs args)
+ {
+ Gtk.FileChooserDialog filechooser = new Gtk.FileChooserDialog ("Choose file",
+ app1, FileChooserAction.Open,
+ "Cancel",ResponseType.Cancel,
+ "Choose",ResponseType.Accept);
+ string dataDir = ForceSensorGraph.GetDataDir(currentSession.UniqueID);
+ filechooser.SetCurrentFolder(dataDir);
+
+ FileFilter file_filter = new FileFilter();
+ file_filter.AddPattern ("*.csv");
+
+ if (filechooser.Run () == (int)ResponseType.Accept)
+ {
+ File.Copy(filechooser.Filename,
+ Path.GetTempPath() + Path.DirectorySeparatorChar + "cj_mif_Data.csv",
+ true); //can be overwritten
+
+ string imagePath = Path.GetTempPath() + Path.DirectorySeparatorChar +
"cj_mif_Graph.png";
+ Util.FileDelete(imagePath);
+ image_force_sensor_graph.Sensitive = false;
+
+ ForceSensorGraph fsg = new ForceSensorGraph(rfdList);
+ bool success = fsg.CallR(
+ viewport_force_sensor_graph.Allocation.Width -5,
+ viewport_force_sensor_graph.Allocation.Height -5);
+
+ if(! success)
+ {
+ new DialogMessage(Constants.MessageTypes.WARNING, "Error doing graph.");
+ filechooser.Destroy ();
+ return;
+ }
+
+ while ( ! Util.FileReadable(imagePath));
+
+ image_force_sensor_graph = UtilGtk.OpenImageSafe(
+ imagePath,
+ image_force_sensor_graph);
+ image_force_sensor_graph.Sensitive = true;
+ }
+ filechooser.Destroy ();
+ }
+
private void on_button_force_sensor_data_folder_clicked (object o, EventArgs args)
{
- System.IO.DirectoryInfo folderSession =
- new System.IO.DirectoryInfo(Util.GetForceSensorSessionDir(currentSession.UniqueID));
- System.IO.DirectoryInfo folderGeneric =
- new System.IO.DirectoryInfo(Util.GetForceSensorDir());
-
- if(folderSession.Exists)
-
System.Diagnostics.Process.Start(Util.GetForceSensorSessionDir(currentSession.UniqueID));
- else if(folderGeneric.Exists)
- System.Diagnostics.Process.Start(Util.GetForceSensorDir());
+ string dataDir = ForceSensorGraph.GetDataDir(currentSession.UniqueID);
+ if(dataDir != "")
+ System.Diagnostics.Process.Start(dataDir);
else
new DialogMessage(Constants.MessageTypes.WARNING, Constants.DirectoryCannotOpen);
}
diff --git a/src/utilEncoder.cs b/src/utilEncoder.cs
index a29780f..bdf1494 100644
--- a/src/utilEncoder.cs
+++ b/src/utilEncoder.cs
@@ -251,7 +251,7 @@ public class UtilEncoder
return System.IO.Path.Combine(Util.GetDataDir(), "r-scripts");
}
public static string GetmifScript() {
- return System.IO.Path.Combine(GetSprintPath(), "maximumisometricForce.R");
+ return System.IO.Path.Combine(GetSprintPath(), "maximumIsometricForce.R");
}
/********** end of r-scripts paths ************/
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]