[chronojump] Encoder util.R calcules work and impulse
- From: Xavier de Blas <xaviblas src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [chronojump] Encoder util.R calcules work and impulse
- Date: Thu, 31 Oct 2019 13:00:25 +0000 (UTC)
commit d56596d727ee4db8f0fd5418126b7b79446438ed
Author: Xavier de Blas <xaviblas gmail com>
Date: Thu Oct 31 13:59:37 2019 +0100
Encoder util.R calcules work and impulse
encoder/capture.R | 2 ++
encoder/graph.R | 13 +++++--
encoder/util.R | 39 +++++++++++++++++++--
src/encoder.cs | 20 ++++++++---
src/gui/encoder.cs | 6 ++--
src/gui/encoderTreeviews.cs | 83 +++++++++++++++++++++++++++++++++++++++------
6 files changed, 141 insertions(+), 22 deletions(-)
---
diff --git a/encoder/capture.R b/encoder/capture.R
index d49f859e..3b1ca027 100644
--- a/encoder/capture.R
+++ b/encoder/capture.R
@@ -96,6 +96,8 @@ calcule <- function(displacement, op, curveNum, startInSet)
paf$meanSpeed, paf$maxSpeed, paf$maxSpeedT,
paf$meanPower, paf$peakPower, paf$peakPowerT, paf$pp_ppt,
paf$meanForce, paf$maxForce, paf$maxForceT, paf$maxForce_maxForceT,
+ paf$workJ, # C# will convert to Kcal if needed
+ paf$impulse,
sep=", "), file = con)
close(con)
#if(debug)
diff --git a/encoder/graph.R b/encoder/graph.R
index 58349df6..33f149d1 100644
--- a/encoder/graph.R
+++ b/encoder/graph.R
@@ -1491,10 +1491,14 @@ findPosInPaf <- function(var, option) {
pos = 13
else if(var == "MassExtra")
pos = 14
- else if(var == "Laterality")
+ else if(var == "workJ")
pos = 15
- else if(var == "Inertia")
+ else if(var == "impulse")
pos = 16
+ else if(var == "Laterality")
+ pos = 17
+ else if(var == "Inertia")
+ pos = 18
if( ( var == "Speed" || var == "Power" || var == "Force") & option == "max")
pos=pos+1
@@ -3827,10 +3831,10 @@ doProcess <- function(options)
"pp_ppt",
"meanForce", "maxForce", "maxForceT",
"maxForce_maxForceT",
+ "workJ", "impulse",
"laterality", "inertiaM"
)
-
#Add "Max", "AVG" and "SD" when analyzing, not on "curves", not on "curvesAC"
if(op$Analysis != "curves" && op$Analysis != "curvesAC") {
addSD = FALSE
@@ -3846,6 +3850,7 @@ doProcess <- function(options)
max(pafCurves$pp_ppt),
max(pafCurves$meanForce), max(pafCurves$maxForce),
max(pafCurves$maxForceT),
max(pafCurves$maxForce_maxForceT),
+ max(pafCurves$workJ), max(pafCurves$impulse),
"", max(pafCurves$inertiaM)
)
@@ -3857,6 +3862,7 @@ doProcess <- function(options)
mean(pafCurves$pp_ppt),
mean(pafCurves$meanForce),
mean(pafCurves$maxForce), mean(pafCurves$maxForceT),
mean(pafCurves$maxForce_maxForceT),
+ mean(pafCurves$workJ), mean(pafCurves$impulse),
"", mean(pafCurves$inertiaM)
)
@@ -3869,6 +3875,7 @@ doProcess <- function(options)
sd(pafCurves$pp_ppt),
sd(pafCurves$meanForce),
sd(pafCurves$maxForce), sd(pafCurves$maxForceT),
sd(pafCurves$maxForce_maxForceT),
+ sd(pafCurves$workJ), sd(pafCurves$impulse),
"", sd(pafCurves$inertiaM)
)
diff --git a/encoder/util.R b/encoder/util.R
index dd428f04..c5ec01da 100644
--- a/encoder/util.R
+++ b/encoder/util.R
@@ -658,6 +658,13 @@ kinematicsF <- function(displacement, repOp, smoothingOneEC, smoothingOneC, g, i
#write("kinematicsF speed length and mean,", stderr())
#write(length(speed$y[start:end]), stderr())
#write(mean(speed$y[start:end]), stderr())
+ write("kinematicsF displacement length, displ length", stderr())
+ write(length(displacement), stderr())
+ write(length(displacement[start:end]), stderr())
+
+ speedyangular = 0
+ if(isInertial(repOp$econfName))
+ speedyangular = dynamics$angleSpeed[start:end]
return(list(
displ = displacement[start:end],
@@ -665,7 +672,9 @@ kinematicsF <- function(displacement, repOp, smoothingOneEC, smoothingOneC, g, i
accely = accel$y[start:end],
force = force[start:end],
power = power[start:end],
- mass = mass))
+ mass = mass,
+ speedyangular = speedyangular
+ ))
}
findECPhases <- function(displacement,speed) {
@@ -775,6 +784,30 @@ pafGenerate <- function(eccon, kinematics, massBody, massExtra, laterality, iner
maxForceT <- min(which(abs(kinematics$force) == maxForce))
maxForce_maxForceT <- maxForce / (maxForceT/1000) # ms->s
+ #work calculation
+ #calculating with mean force has the problem that the displacement is not always the same
+ #so is not correct and has to be (at each ms): force * displ
+ #workJ <- meanForce * max(abs(kinematics$displ)) #F * displ # TODO: maybe calculate by phases
with a distance always positive
+
+ #work by difference of energy (Joules)
+ #W = m[g(hf - hi) + 1/2 (vf^2 - Vi^2)] + 1/2 I(wf^2 - wi^2)
+ # <-- on inertial -->
+ #hi, hf: height initial/final
+ #vi, vf: speed initial/final
+ #wi, wf: angular speed initial/final
+ lastValue = length(kinematics$displ)
+ workJ <- kinematics$mass * ( g * (kinematics$displ[lastValue] - kinematics$displ[1]) +
.5*((kinematics$speedy[lastValue])^2 - (kinematics$speedy[1])^2) )
+ if(inertiaMomentum > 0) #if is not inertial Roptions has a -1
+ workJ = workJ + .5 * inertiaMomentum * ( (kinematics$speedyangular[lastValue])^2 -
(kinematics$speedyangular[1]^2) )
+
+ #impulse
+ impulse <- meanForce * length(kinematics$displ)/1000 #F * time in s
+
+ print("meanForce: ")
+ print(meanForce)
+ print("displ: ")
+ print(length(kinematics$displ)/1000)
+
#here paf is generated
#mass is not used by pafGenerate, but used by Kg/W (loadVSPower)
#meanForce and maxForce are not used by pafGenerate, but used by F/S (forceVSSpeed)
@@ -785,7 +818,9 @@ pafGenerate <- function(eccon, kinematics, massBody, massExtra, laterality, iner
meanPower, peakPower, peakPowerT, pp_ppt,
meanForce, maxForce, maxForceT, maxForce_maxForceT,
mass, massBody, massExtra, #kinematics$mass is Load
- laterality, inertiaMomentum))
+ workJ, impulse,
+ laterality, inertiaMomentum
+ ))
}
isInertial <- function(encoderConfigurationName) {
diff --git a/src/encoder.cs b/src/encoder.cs
index 0149309d..1f0cb634 100644
--- a/src/encoder.cs
+++ b/src/encoder.cs
@@ -248,6 +248,8 @@ public class EncoderCurve
public string MaxForce;
public string MaxForceT;
public string MaxForce_MaxForceT;
+ public string WorkJ;
+ public string Impulse;
public EncoderCurve () {
}
@@ -259,7 +261,8 @@ public class EncoderCurve
string meanPower, string peakPower, string peakPowerT,
string PP_PPT,
string meanForce, string maxForce, string maxForceT,
- string maxForce_maxForceT
+ string maxForce_maxForceT,
+ string workJ, string impulse
)
{
this.Record = record;
@@ -278,6 +281,8 @@ public class EncoderCurve
this.MaxForce = maxForce;
this.MaxForceT = maxForceT;
this.MaxForce_MaxForceT = maxForce_maxForceT;
+ this.WorkJ = workJ;
+ this.Impulse = impulse;
}
//used on TreeView analyze
@@ -290,7 +295,8 @@ public class EncoderCurve
string meanPower, string peakPower, string peakPowerT,
string PP_PPT,
string meanForce, string maxForce, string maxForceT,
- string maxForce_maxForceT)
+ string maxForce_maxForceT,
+ string workJ, string impulse)
{
this.N = n;
this.Series = series;
@@ -313,6 +319,8 @@ public class EncoderCurve
this.MaxForce = maxForce;
this.MaxForceT = maxForceT;
this.MaxForce_MaxForceT = maxForce_maxForceT;
+ this.WorkJ = workJ;
+ this.Impulse = impulse;
}
public EncoderCurve Copy()
@@ -323,7 +331,8 @@ public class EncoderCurve
MeanPower, PeakPower, PeakPowerT,
PP_PPT,
MeanForce, MaxForce, MaxForceT,
- MaxForce_MaxForceT);
+ MaxForce_MaxForceT,
+ WorkJ, Impulse);
return curveCopy;
}
@@ -415,7 +424,8 @@ public class EncoderCurve
MeanPower + sep + PeakPower + sep + PeakPowerT + sep +
PP_PPT + sep +
MeanForce + sep + MaxForce + sep + MaxForceT + sep +
- MaxForce_MaxForceT;
+ MaxForce_MaxForceT + sep +
+ WorkJ + sep + Impulse;
if(decimalSeparator == "COMMA")
str = Util.ConvertToComma(str);
@@ -435,6 +445,8 @@ public class EncoderCurve
public double MeanForceD { get { return Convert.ToDouble(MeanForce); } }
public double MaxForceD { get { return Convert.ToDouble(MaxForce); } }
+ public double WorkJD { get { return Convert.ToDouble(WorkJ); } }
+ public double WorkKcalD { get { return Convert.ToDouble(WorkJ) * 0.000239006; } }
~EncoderCurve() {}
}
diff --git a/src/gui/encoder.cs b/src/gui/encoder.cs
index 3a6983f3..9eee089e 100644
--- a/src/gui/encoder.cs
+++ b/src/gui/encoder.cs
@@ -5448,7 +5448,8 @@ public partial class ChronoJumpWindow
",series,exercise,mass,start,width,height," +
"meanSpeed,maxSpeed,maxSpeedT," +
"meanPower,peakPower,peakPowerT,pp_ppt," +
- "meanForce, maxForce, maxForceT, maxForce_maxForceT");
+ "meanForce, maxForce, maxForceT, maxForce_maxForceT," +
+ "workJ, impulse");
string filename = UtilEncoder.GetEncoderCaptureTempFileName();
if(File.Exists(filename))
@@ -5835,7 +5836,8 @@ public partial class ChronoJumpWindow
strs[7], strs[8], strs[9], //powers
strs[10], //pp/ppt
strs[11], strs[12], strs[13], //forces
- strs[14] //maxForce_maxForceT
+ strs[14], //maxForce_maxForceT
+ strs[15], strs[16] //workJ, impulse
));
//LogB.Debug("encoderCaptureStringR");
diff --git a/src/gui/encoderTreeviews.cs b/src/gui/encoderTreeviews.cs
index d10d261a..d1d681c6 100644
--- a/src/gui/encoderTreeviews.cs
+++ b/src/gui/encoderTreeviews.cs
@@ -64,6 +64,12 @@ public partial class ChronoJumpWindow
bool showStartAndDuration = preferences.encoderShowStartAndDuration;
+ string workString = Catalog.GetString("Work");
+ if(preferences.encoderWorkKcal)
+ workString += "\n (KCal)";
+ else
+ workString += "\n (J)";
+
string [] columnsString = {
Catalog.GetString("n") + "\n",
Catalog.GetString("Start") + "\n (s)",
@@ -79,7 +85,9 @@ public partial class ChronoJumpWindow
"F" + "\n (N)",
"Fmax" + "\n (N)",
"t->Fmax" + "\n (s)",
- "RFD" + "\n (N/s)"
+ "RFD" + "\n (N/s)",
+ workString,
+ Catalog.GetString("Impulse") + "\n (N*s)"
};
encoderCaptureCurves = new ArrayList ();
@@ -131,7 +139,8 @@ public partial class ChronoJumpWindow
cells[11], cells[12], cells[13],//meanPower, peakPower,
peakPowerT
cells[14], //peakPower / peakPowerT
cells[15], cells[16], cells[17], //meanForce, maxForce
maxForceT
- cells[18] //meanForce / meanForceT
+ cells[18], //meanForce / meanForceT
+ cells[19], cells[20] //work, impulse
));
}
@@ -232,6 +241,12 @@ public partial class ChronoJumpWindow
case 14:
aColumn.SetCellDataFunc (aCell, new Gtk.TreeCellDataFunc
(RenderMaxForce_maxForceT));
break;
+ case 15:
+ aColumn.SetCellDataFunc (aCell, new Gtk.TreeCellDataFunc
(RenderWork));
+ break;
+ case 16:
+ aColumn.SetCellDataFunc (aCell, new Gtk.TreeCellDataFunc
(RenderImpulse));
+ break;
}
if( ! ( (i == 1 || i == 2) && ! showStartAndDuration ) )
@@ -568,6 +583,12 @@ public partial class ChronoJumpWindow
distanceUnits = "(mm)";
}
+ string workString = Catalog.GetString("Work");
+ if(preferences.encoderWorkKcal)
+ workString += "\n (KCal)";
+ else
+ workString += "\n (J)";
+
string [] treeviewEncoderAnalyzeHeaders = {
Catalog.GetString("Repetition") + "\n",
Catalog.GetString("Series") + "\n",
@@ -589,7 +610,9 @@ public partial class ChronoJumpWindow
"F" + "\n(N)",
"Fmax" + "\n(N)",
"t->Fmax" + "\n" + timeUnits,
- "RFD" + "\n(N/s)"
+ "RFD" + "\n(N/s)",
+ workString,
+ Catalog.GetString("Impulse") + "\n (N*s)"
};
return treeviewEncoderAnalyzeHeaders;
}
@@ -666,16 +689,17 @@ public partial class ChronoJumpWindow
cells[0],
cells[1], //seriesName
exerciseName,
- cells[19], //laterality
+ cells[21], //laterality
Convert.ToDouble(Util.ChangeDecimalSeparator(cells[4])), //extraWeight
totalMass,
//displaceWeight
- Convert.ToInt32(cells[20]),
//inertia
+ Convert.ToInt32(cells[22]),
//inertia
cells[5], cells[6], cells[7],
cells[8], cells[9], cells[10],
cells[11], cells[12], cells[13],
cells[14],
cells[15], cells[16], cells[17], //meanForce,
maxSForce maxForceT
- cells[18]
+ cells[18],
+ cells[19], cells[20]
));
} while(true);
@@ -771,6 +795,12 @@ public partial class ChronoJumpWindow
case 20:
aColumn.SetCellDataFunc (aCell, new Gtk.TreeCellDataFunc
(RenderMaxForce_maxForceT));
break;
+ case 21:
+ aColumn.SetCellDataFunc (aCell, new Gtk.TreeCellDataFunc
(RenderWork));
+ break;
+ case 22:
+ aColumn.SetCellDataFunc (aCell, new Gtk.TreeCellDataFunc
(RenderImpulse));
+ break;
}
treeview_encoder_analyze_curves.AppendColumn (aColumn);
@@ -1355,6 +1385,29 @@ public partial class ChronoJumpWindow
renderBoldIfNeeded(cell, curve, str);
}
+ private void RenderWork (Gtk.TreeViewColumn column, Gtk.CellRenderer cell, Gtk.TreeModel model,
Gtk.TreeIter iter)
+ {
+ EncoderCurve curve = (EncoderCurve) model.GetValue (iter, 0);
+
+ double workValueD = curve.WorkJD;
+ int decimals = 1;
+ if(preferences.encoderWorkKcal)
+ {
+ workValueD = curve.WorkKcalD;
+ decimals = 3;
+ }
+
+ string str = String.Format(UtilGtk.TVNumPrint(workValueD.ToString(),6, decimals), workValueD);
+ renderBoldIfNeeded(cell, curve, str);
+ }
+
+ private void RenderImpulse (Gtk.TreeViewColumn column, Gtk.CellRenderer cell, Gtk.TreeModel model,
Gtk.TreeIter iter)
+ {
+ EncoderCurve curve = (EncoderCurve) model.GetValue (iter, 0);
+ string str =
String.Format(UtilGtk.TVNumPrint(curve.Impulse,6,3),Convert.ToDouble(curve.Impulse));
+ renderBoldIfNeeded(cell, curve, str);
+ }
+
/* end of rendering capture and analyze cols */
/* start rendering neuromuscular cols */
@@ -1468,9 +1521,9 @@ public partial class ChronoJumpWindow
private bool fixDecimalsWillWork(bool captureOrAnalyze, string [] cells)
{
LogB.Information(string.Format("captureOrAnalyze: {0}, cells.Length: {1}", captureOrAnalyze,
cells.Length));
- if(captureOrAnalyze && cells.Length < 19) //from 0 to 18
+ if(captureOrAnalyze && cells.Length < 21) //from 0 to 20
return false;
- else if(! captureOrAnalyze && cells.Length < 21) //from 0 to 20
+ else if(! captureOrAnalyze && cells.Length < 23) //from 0 to 22
return false;
return true;
@@ -1478,6 +1531,8 @@ public partial class ChronoJumpWindow
//captureOrAnalyze is true on capture, false on analyze
private string [] fixDecimals(bool captureOrAnalyze, string [] cells)
{
+ LogB.Information("fixDecimals: ");
+ LogB.Information(Util.StringArrayToString(cells, ";"));
//start, width, height
for(int i=5; i <= 7; i++)
cells[i] =
Util.TrimDecimals(Convert.ToDouble(Util.ChangeDecimalSeparator(cells[i])),1);
@@ -1498,13 +1553,19 @@ public partial class ChronoJumpWindow
int maxForce_maxForceT = 18;
cells[maxForce_maxForceT] =
Util.TrimDecimals(Convert.ToDouble(Util.ChangeDecimalSeparator(cells[maxForce_maxForceT])),1);
- //cells[19] laterality
+ LogB.Information("cells19: " + cells[19]);
+ LogB.Information("cells20: " + cells[20]);
+ //work, impulse
+ cells[19] = Util.TrimDecimals(Convert.ToDouble(Util.ChangeDecimalSeparator(cells[19])),3);
+ cells[20] = Util.TrimDecimals(Convert.ToDouble(Util.ChangeDecimalSeparator(cells[20])),3);
+
+ //cells[21] laterality
//capture does not return inerta
//analyze returns inertia (can be different on "saved curves") comes as Kg*m^2, convert it to
Kg*cm^2
if(! captureOrAnalyze) {
- double inertiaInM = Convert.ToDouble(Util.ChangeDecimalSeparator(cells[20]));
- cells[20] = (Convert.ToInt32(inertiaInM * 10000)).ToString();
+ double inertiaInM = Convert.ToDouble(Util.ChangeDecimalSeparator(cells[22]));
+ cells[22] = (Convert.ToInt32(inertiaInM * 10000)).ToString();
}
return cells;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]