[chronojump] ForceSensor realtime graph with ablines, and other improvements
- From: Xavier de Blas <xaviblas src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [chronojump] ForceSensor realtime graph with ablines, and other improvements
- Date: Tue, 31 Oct 2017 13:35:25 +0000 (UTC)
commit 5e18524013a16e1779b78d1ae359943dbb66ee39
Author: Xavier de Blas <xaviblas gmail com>
Date: Tue Oct 31 13:26:10 2017 +0100
ForceSensor realtime graph with ablines, and other improvements
src/forceSensor.cs | 33 +++++++---
src/gui/forceSensor.cs | 169 +++++++++++++++++++++++++++++++-----------------
2 files changed, 133 insertions(+), 69 deletions(-)
---
diff --git a/src/forceSensor.cs b/src/forceSensor.cs
index ec91459..e80e0cb 100644
--- a/src/forceSensor.cs
+++ b/src/forceSensor.cs
@@ -39,8 +39,8 @@ public class ForceSensorCapturePoints
private List<int> times;
private List<double> forces;
- public int RealWidthG = 10000000; //width of graph in microseconds (will be upgraded if needed)
- public int RealHeightG = 500; //Newtons (will be upgraded if needed)
+ public int RealWidthG; //width of graph in microseconds (will be upgraded if needed)
+ public int RealHeightG; //Newtons (will be upgraded if needed)
private int widthG;
private int heightG;
@@ -56,10 +56,18 @@ public class ForceSensorCapturePoints
times = new List<int>();
forces = new List<double>();
+ InitRealWidthHeight();
+
this.widthG = widthG;
this.heightG = heightG;
}
+ public void InitRealWidthHeight()
+ {
+ RealWidthG = 10000000; //width of graph in microseconds (will be upgraded if needed)
+ RealHeightG = 1; //Newtons (will be upgraded when needed)
+ }
+
public void Add(int time, double force)
{
times.Add(time);
@@ -104,17 +112,24 @@ public class ForceSensorCapturePoints
return false;
}
// this is called at load signal, checks if last X is outside the graph and max/min force
- public bool OutsideGraph(int lastTime, double minForce, double maxForce)
+ public bool OutsideGraph(int lastTime, double maxForce, double minForce)
{
- RealWidthG = lastTime + GetTimeInPx(marginLeft) + GetTimeInPx(marginRight);
+ if(lastTime + GetTimeInPx(marginLeft) + GetTimeInPx(marginRight) > RealWidthG ||
+ GetForceInPx(minForce) > heightG ||
+ GetForceInPx(maxForce) < 0)
+ {
+ RealWidthG = lastTime + GetTimeInPx(marginLeft) + GetTimeInPx(marginRight);
- double absoluteMaxForce = maxForce;
- if(Math.Abs(minForce) > absoluteMaxForce)
- absoluteMaxForce = Math.Abs(minForce);
+ double absoluteMaxForce = maxForce;
+ if(Math.Abs(minForce) > absoluteMaxForce)
+ absoluteMaxForce = Math.Abs(minForce);
- RealHeightG = Convert.ToInt32(2 * absoluteMaxForce + absoluteMaxForce * .2);
+ RealHeightG = Convert.ToInt32(2 * absoluteMaxForce + absoluteMaxForce * .2);
- return true;
+ return true;
+ }
+
+ return false;
}
public void Redo()
diff --git a/src/gui/forceSensor.cs b/src/gui/forceSensor.cs
index a48cf7d..cafefdc 100644
--- a/src/gui/forceSensor.cs
+++ b/src/gui/forceSensor.cs
@@ -29,6 +29,36 @@ using System.Text; //StringBuilder
using System.Collections.Generic; //List<T>
using Mono.Unix;
+//struct with relevant data used on various functions and threads
+public class ForceSensorValues
+{
+ public int TimeLast; //store last time
+ public int TimeForceMax; //store time of max force
+ public double ForceLast; //store last force
+ public double ForceMax; //store max force
+ public double ForceMin; //store min force
+
+ public ForceSensorValues()
+ {
+ TimeLast = 0;
+ TimeForceMax = 0;
+ ForceLast = 0;
+ ForceMax = 0;
+ ForceMin = 10000;
+ }
+
+ public void SetMaxMinIfNeeded(double force, int time)
+ {
+ if(force > ForceMax)
+ {
+ ForceMax = force;
+ TimeForceMax = time;
+ }
+ if(force < ForceMin)
+ ForceMin = force;
+ }
+}
+
public partial class ChronoJumpWindow
{
[Widget] Gtk.HBox hbox_force_buttons;
@@ -70,7 +100,7 @@ public partial class ChronoJumpWindow
static bool redoingPoints; //don't draw while redoing points (adjusting screen)
static bool forceCaptureStartMark; //Just needed to display "Capturing message"
- static double forceSensorLast; //Needed to display value and move vscale
+ static ForceSensorValues forceSensorValues;
string forceSensorPortName;
SerialPort portFS; //Attention!! Don't reopen port because arduino makes reset and tare,
calibration... is lost
@@ -411,7 +441,16 @@ public partial class ChronoJumpWindow
forceProcessFinish = false;
forceProcessCancel = false;
- forceSensorLast = 0;
+
+ //initialize
+ forceSensorValues = new ForceSensorValues();
+
+ UtilGtk.ErasePaint(force_capture_drawingarea, force_capture_pixmap);
+ fscPoints = new ForceSensorCapturePoints(
+ force_capture_drawingarea.Allocation.Width,
+ force_capture_drawingarea.Allocation.Height
+ );
+ forcePaintHVLines(fscPoints.RealHeightG, -1 * fscPoints.RealHeightG, 10);
event_execute_ButtonFinish.Clicked -= new EventHandler(on_finish_clicked);
event_execute_ButtonFinish.Clicked += new EventHandler(on_finish_clicked);
@@ -461,11 +500,6 @@ public partial class ChronoJumpWindow
writer.WriteLine("Time (s);Force(N)");
str = "";
int firstTime = 0;
- fscPoints = new ForceSensorCapturePoints(
- force_capture_drawingarea.Allocation.Width,
- force_capture_drawingarea.Allocation.Height
- );
- UtilGtk.ErasePaint(force_capture_drawingarea, force_capture_pixmap);
while(! forceProcessFinish && ! forceProcessCancel)
{
@@ -496,9 +530,12 @@ public partial class ChronoJumpWindow
time -= firstTime;
double force = Convert.ToDouble(Util.ChangeDecimalSeparator(strFull[1]));
-
writer.WriteLine(time.ToString() + ";" + force.ToString());
- forceSensorLast = force;
+
+ forceSensorValues.TimeLast = time;
+ forceSensorValues.ForceLast = force;
+
+ forceSensorValues.SetMaxMinIfNeeded(force, time);
fscPoints.Add(time, force);
fscPoints.NumCaptured ++;
@@ -557,6 +594,9 @@ LogB.Information(" fc C ");
{
event_execute_label_message.Text = "Saved.";
Thread.Sleep (250); //Wait a bit to ensure is copied
+
+ fscPoints.InitRealWidthHeight();
+ forceSensorDoSignalGraphPlot();
forceSensorDoRFDGraph();
}
} else if(forceProcessCancel)
@@ -598,27 +638,25 @@ LogB.Information(" fc G ");
int lower = Convert.ToInt32(vscale_force_sensor.Adjustment.Lower);
bool changed = false;
- if(forceSensorLast > upper)
+ if(forceSensorLastCaptured > upper)
{
- upper = Convert.ToInt32(forceSensorLast * 2);
+ upper = Convert.ToInt32(forceSensorLastCaptured * 2);
changed = true;
}
- if(forceSensorLast < lower)
+ if(forceSensorLastCaptured < lower)
{
- lower = Convert.ToInt32(forceSensorLast * 2); //good for negative values
+ lower = Convert.ToInt32(forceSensorLastCaptured * 2); //good for negative
values
changed = true;
}
if(changed)
vscale_force_sensor.SetRange(lower, upper);
//B) change the value
- vscale_force_sensor.Value = forceSensorLast;
+ vscale_force_sensor.Value = forceSensorLastCaptured;
*/
- label_force_sensor_value.Text = forceSensorLast.ToString();
- if(forceSensorLast > Convert.ToDouble(label_force_sensor_value_max.Text))
- label_force_sensor_value_max.Text = forceSensorLast.ToString();
- if(forceSensorLast < Convert.ToDouble(label_force_sensor_value_min.Text))
- label_force_sensor_value_min.Text = forceSensorLast.ToString();
+ label_force_sensor_value.Text = forceSensorValues.ForceLast.ToString();
+ label_force_sensor_value_max.Text = forceSensorValues.ForceMax.ToString();
+ label_force_sensor_value_min.Text = forceSensorValues.ForceMin.ToString();
LogB.Information(" fc H ");
@@ -630,6 +668,7 @@ LogB.Information(" fc I ");
//mark meaning screen should be erased
if(fscPoints.NumPainted == -1) {
UtilGtk.ErasePaint(force_capture_drawingarea, force_capture_pixmap);
+ forcePaintHVLines(forceSensorValues.ForceMax, forceSensorValues.ForceMin,
fscPoints.RealWidthG);
fscPoints.NumPainted = 0;
}
@@ -816,22 +855,22 @@ LogB.Information(" fc R ");
void forceSensorDoSignalGraph()
{
+ forceSensorDoSignalGraphReadFile();
+ forceSensorDoSignalGraphPlot();
+ }
+ void forceSensorDoSignalGraphReadFile()
+ {
fscPoints = new ForceSensorCapturePoints(
force_capture_drawingarea.Allocation.Width,
force_capture_drawingarea.Allocation.Height
);
- UtilGtk.ErasePaint(force_capture_drawingarea, force_capture_pixmap);
-
- if(pen_black_force_capture == null)
- force_graphs_init();
List<string> contents = Util.ReadFileAsStringList(UtilEncoder.GetmifCSVFileName());
bool headersRow = true;
- double maxForce = 0;
- double minForce = 0;
- int lastTime = 0;
- int maxForceTime = 0; //time at maxForce
- double lastForce = 0;
+
+ //initialize
+ forceSensorValues = new ForceSensorValues();
+
foreach(string str in contents)
{
if(headersRow)
@@ -848,31 +887,62 @@ LogB.Information(" fc R ");
if(Util.IsNumber(strFull[0], false) && Util.IsNumber(strFull[1], true))
{
+ int time = Convert.ToInt32(strFull[0]);
double force = Convert.ToDouble(strFull[1]);
- fscPoints.Add(Convert.ToInt32(strFull[0]), force);
+
+ fscPoints.Add(time, force);
fscPoints.NumCaptured ++;
- lastTime = Convert.ToInt32(strFull[0]);
- lastForce = force;
- if(force > maxForce)
- {
- maxForce = force;
- maxForceTime = lastTime;
- }
- if(force < minForce)
- minForce = force;
+ forceSensorValues.TimeLast = time;
+ forceSensorValues.ForceLast = force;
+ forceSensorValues.SetMaxMinIfNeeded(force, time);
}
}
}
+ }
+ void forceSensorDoSignalGraphPlot()
+ {
+ UtilGtk.ErasePaint(force_capture_drawingarea, force_capture_pixmap);
+
+ if(pen_black_force_capture == null)
+ force_graphs_init();
/*
* redo the graph if last point time is greater than RealWidthG
* or if GetForceInPx(minForce) < 0
* or if getForceInPx(maxForce) > heightG
*/
- if(fscPoints.OutsideGraph(lastTime, minForce, maxForce))
+ if(fscPoints.OutsideGraph(forceSensorValues.TimeLast, forceSensorValues.ForceMax,
forceSensorValues.ForceMin))
fscPoints.Redo();
+ forcePaintHVLines(forceSensorValues.ForceMax, forceSensorValues.ForceMin,
forceSensorValues.TimeLast);
+
+ Gdk.Point [] paintPoints = new Gdk.Point[fscPoints.Points.Count];
+ for(int i = 0; i < fscPoints.Points.Count; i ++)
+ paintPoints[i] = fscPoints.Points[i];
+
+ force_capture_pixmap.DrawLines(pen_black_force_capture, paintPoints);
+
+ //draw rectangle in maxForce
+ //force_capture_pixmap.DrawRectangle(pen_red_force_capture, false,
+ // new Gdk.Rectangle(fscPoints.GetTimeInPx(maxForceTime) -5,
fscPoints.GetForceInPx(maxForce) -5, 10, 10));
+
+ //draw circle in maxForce
+ force_capture_pixmap.DrawArc(pen_red_force_capture, false,
+ fscPoints.GetTimeInPx(forceSensorValues.TimeForceMax) -6,
+ fscPoints.GetForceInPx(forceSensorValues.ForceMax) -6,
+ 12, 12, 90 * 64, 360 * 64);
+
+ force_capture_drawingarea.QueueDraw(); // -- refresh
+
+ label_force_sensor_value.Text = forceSensorValues.ForceLast.ToString();
+ label_force_sensor_value_max.Text = forceSensorValues.ForceMax.ToString();
+ label_force_sensor_value_min.Text = forceSensorValues.ForceMin.ToString();
+ button_force_sensor_image_save_signal.Sensitive = true;
+ }
+
+ private void forcePaintHVLines(double maxForce, double minForce, int lastTime)
+ {
forcePaintHLine(0);
double absoluteMaxForce = maxForce;
if(Math.Abs(minForce) > absoluteMaxForce)
@@ -901,27 +971,6 @@ LogB.Information(" fc R ");
for(int i = 0; i <= lastTimeInSeconds ; i += step)
forcePaintTimeValue(i);
-
- Gdk.Point [] paintPoints = new Gdk.Point[fscPoints.Points.Count];
- for(int i = 0; i < fscPoints.Points.Count; i ++)
- paintPoints[i] = fscPoints.Points[i];
-
- force_capture_pixmap.DrawLines(pen_black_force_capture, paintPoints);
-
- //draw rectangle in maxForce
- //force_capture_pixmap.DrawRectangle(pen_red_force_capture, false,
- // new Gdk.Rectangle(fscPoints.GetTimeInPx(maxForceTime) -5,
fscPoints.GetForceInPx(maxForce) -5, 10, 10));
-
- //draw circle in maxForce
- force_capture_pixmap.DrawArc(pen_red_force_capture, false,
- fscPoints.GetTimeInPx(maxForceTime) -6, fscPoints.GetForceInPx(maxForce) -6,
12, 12, 90 * 64, 360 * 64);
-
- force_capture_drawingarea.QueueDraw(); // -- refresh
-
- label_force_sensor_value.Text = lastForce.ToString();
- label_force_sensor_value_max.Text = maxForce.ToString();
- label_force_sensor_value_min.Text = minForce.ToString();
- button_force_sensor_image_save_signal.Sensitive = true;
}
private void forcePaintTimeValue(int time)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]