[chronojump] Realtime capture on inertial almost perfect on eccon=="c"
- From: Xavier de Blas <xaviblas src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [chronojump] Realtime capture on inertial almost perfect on eccon=="c"
- Date: Wed, 18 Feb 2015 18:07:10 +0000 (UTC)
commit 3445facdecce6b734a56cf1bb26641a9fb05da17
Author: Xavier de Blas <xaviblas gmail com>
Date: Wed Feb 18 19:06:15 2015 +0100
Realtime capture on inertial almost perfect on eccon=="c"
encoder/capture.R | 138 ++++++++++++++++++++++++++++++----------------------
encoder/graph.R | 5 +-
encoder/util.R | 32 +++++++++---
src/gui/encoder.cs | 52 ++++++++++++++++---
src/utilEncoder.cs | 15 ++++--
5 files changed, 162 insertions(+), 80 deletions(-)
---
diff --git a/encoder/capture.R b/encoder/capture.R
index 86380a5..6f75c83 100644
--- a/encoder/capture.R
+++ b/encoder/capture.R
@@ -29,7 +29,7 @@ source(scriptUtilR)
g = 9.81
-calcule <- function(displacement, op)
+calcule <- function(displacement, start, end, op)
{
#read AnalysisOptions
#if is propulsive and rotatory inertial is: "p;ri"
@@ -66,77 +66,99 @@ calcule <- function(displacement, op)
#do not use print because it shows the [1] first. Use cat:
cat(paste(#start, #start is not used because we have no data of the initial zeros
- (end-start), (position[end]-position[start]),
+ #(end-start), (position[end]-position[start]), #this is not used because the start, end
values are not ok now
+ 0, 0,
paf$meanSpeed, paf$maxSpeed, paf$maxSpeedT, paf$meanPower, paf$peakPower, paf$peakPowerT,
paf$pp_ppt, sep=", "))
cat("\n") #mandatory to read this from C#, but beware, there we will need a trim to remove the
windows \r\n
}
-
-input <- readLines(f, n = 1L)
-while(input[1] != "Q") {
- #Sys.sleep(4) #just to test how Chronojump reacts if process takes too long
- #cat(paste("input is:", input, "\n"))
-
+
+getPositionStart <- function(input)
+{
+ inputVector = unlist(strsplit(input, " "))
+ if( length(inputVector) == 2 && inputVector[1] == "ps" )
+ return (as.numeric(inputVector[2]))
+ else
+ return (0)
+}
+
+doProcess <- function()
+{
op <- assignOptions(options)
#print ("----op----")
#print (op)
+
+ input <- readLines(f, n = 1L)
+ while(input[1] != "Q") {
+ #Sys.sleep(4) #just to test how Chronojump reacts if process takes too long
+ #cat(paste("input is:", input, "\n"))
- displacement = as.numeric(unlist(strsplit(input, " ")))
- #if data file ends with comma. Last character will be an NA. remove it
- #this removes all NAs
- displacement = displacement[!is.na(displacement)]
-
- if(isInertial(op$EncoderConfigurationName))
- {
- displacement = fixDisplacementInertial(displacement, op$EncoderConfigurationName,
op$diameter, op$diameterExt)
+ #from Chronojump first it's send the eg: "ps -1000", meaning curve starts at -1000
+ #then it's send the displacement
+ positionStart = getPositionStart(input)
+ input <- readLines(f, n = 1L)
- displacement = getDisplacementInertialBody(displacement, FALSE, op$Title) #draw: FALSE
- } else {
- displacement = getDisplacement(op$EncoderConfigurationName, displacement, op$diameter,
op$diameterExt)
- }
-
- start = 1
- end = length(displacement)
- if( ! isInertial(op$EncoderConfigurationName)) {
- reduceTemp = reduceCurveBySpeed(op$Eccon, 1,
- 1, 0, #startT, startH
- displacement, #displacement
- op$SmoothingOneC #SmoothingOneC
- )
-
- start = reduceTemp[1]
- end = reduceTemp[2]
- #write("printing reduceTemp2", stderr())
- #write(reduceTemp[2], stderr())
- if(end > length(displacement))
- end = length(displacement)
-
- displacement = displacement[start:end]
- }
+ displacement = as.numeric(unlist(strsplit(input, " ")))
+ #if data file ends with comma. Last character will be an NA. remove it
+ #this removes all NAs
+ displacement = displacement[!is.na(displacement)]
+
+
+ if(isInertial(op$EncoderConfigurationName))
+ {
+ displacement = fixDisplacementInertial(displacement, op$EncoderConfigurationName,
op$diameter, op$diameterExt)
- #if isInertial: getDisplacementInertialBody separate phases using initial height of full extended
person
- #so now there will be two different curves to process
- if(isInertial(op$EncoderConfigurationName))
- {
- position = cumsum(displacement)
- positionBottom <- floor(mean(which(position == min(position))))
- displacement1 = displacement[1:positionBottom]
- calcule(displacement1, op)
-
- if( (positionBottom +1) < length(displacement)){
- displacement2 = displacement[(positionBottom+1):length(displacement)]
- calcule(displacement2, op)
+ displacement = getDisplacementInertialBody(positionStart, displacement, FALSE,
op$Title) #draw: FALSE
+ } else {
+ displacement = getDisplacement(op$EncoderConfigurationName, displacement,
op$diameter, op$diameterExt)
}
- write(c("positionBottom", positionBottom), stderr())
- write(c("length(displacement)", length(displacement)), stderr())
- } else {
- calcule(displacement, op)
- }
- input <- readLines(f, n = 1L)
+ start = 1
+ end = length(displacement)
+ if( ! isInertial(op$EncoderConfigurationName)) {
+ reduceTemp = reduceCurveBySpeed(op$Eccon, 1,
+ 1, 0, #startT, startH
+ displacement, #displacement
+ op$SmoothingOneC #SmoothingOneC
+ )
+
+ start = reduceTemp[1]
+ end = reduceTemp[2]
+ #write("printing reduceTemp2", stderr())
+ #write(reduceTemp[2], stderr())
+ if(end > length(displacement))
+ end = length(displacement)
+
+ displacement = displacement[start:end]
+ }
+
+ #if isInertial: getDisplacementInertialBody separate phases using initial height of full
extended person
+ #so now there will be two different curves to process
+ if(isInertial(op$EncoderConfigurationName))
+ {
+ position = cumsum(displacement)
+ positionTop <- floor(mean(which(position == max(position))))
+ displacement1 = displacement[1:positionTop]
+ displacement2 = displacement[(positionTop+1):length(displacement)]
+
+ if(op$Eccon == "c") {
+ calcule(displacement1, start, end, op) #TODO: check this start, end
+ } else {
+ calcule(displacement1, start, end, op) #TODO: check this start, end
+ calcule(displacement2, start, end, op) #TODO: check this start, end
+ }
+
+ #write(c("positionTop", positionTop), stderr())
+ #write(c("length(displacement)", length(displacement)), stderr())
+ } else {
+ calcule(displacement, start, end, op) #TODO: check this start, end
+ }
+
+ input <- readLines(f, n = 1L)
+ }
}
-
+doProcess()
write("Ending capture.R", stderr())
quit()
diff --git a/encoder/graph.R b/encoder/graph.R
index ff27e0f..2b8eb87 100644
--- a/encoder/graph.R
+++ b/encoder/graph.R
@@ -1869,8 +1869,9 @@ doProcess <- function(options)
if(isInertial(op$EncoderConfigurationName))
{
displacement = fixDisplacementInertial(displacement, op$EncoderConfigurationName,
op$diameter, op$diameterExt)
-
- displacement = getDisplacementInertialBody(displacement, curvesPlot, op$Title)
+
+ displacement = getDisplacementInertialBody(0, displacement, curvesPlot, op$Title)
+ #positionStart is 0 in graph.R. It is different on capture.R because depends on the
start of every repetition
curvesPlot = FALSE
} else {
diff --git a/encoder/util.R b/encoder/util.R
index f67fe37..d4ec45d 100644
--- a/encoder/util.R
+++ b/encoder/util.R
@@ -675,7 +675,12 @@ getDynamicsInertial <- function(encoderConfigurationName, displacement, d, D, ma
#this methods replaces getDisplacement and fixRawdataInertial
#here comes a signal: (singleFile)
#it shows the disc rotation and the person movement
-getDisplacementInertialBody <- function(displacement, draw, title)
+
+#positionStart is the height at the start of the curve. It's used only on realtime capture.
+#displacementPerson has to be adjusted for every repetition using the positionStart relative to the start of
the movement
+#Eg, at start of the capture position is always 0, then goes down (first eccentric phase), and then starts
con-ecc, con-ecc, con-ecc, ...
+#To divide the con-ecc in two phases (because for the encoder is only one phsae because it rotates in the
same direction), we need to know the positionAtStart
+getDisplacementInertialBody <- function(positionStart, displacement, draw, title)
{
position=cumsum(displacement)
position.ext=extrema(position)
@@ -685,23 +690,36 @@ getDisplacementInertialBody <- function(displacement, draw, title)
#do if extrema(position)$nextreme == 0... then do not use extrema
#TODO: check if started backwards on realtime capture (extrema is null)
- firstDownPhaseTime = 1
- downHeight = 0
+ #firstDownPhaseTime = 1
+ #downHeight = 0
if( position.ext$nextreme > 0 && ! is.null(position.ext$minindex) && ! is.null(position.ext$maxindex)
) {
#Fix if disc goes wrong direction at start
- if(position.ext$maxindex[1] < position.ext$minindex[1]) {
+ #we know this because we found a maxindex before than a minindex, and
+ #this maxindex is not an small movement, at least is 20% of the movement
+ if(
+ ( position.ext$maxindex[1] < position.ext$minindex[1] ) &&
+ ( position[position.ext$maxindex[1]] >= ( max(abs(position)) *.2 ) ) ) {
displacement = displacement * -1
position=cumsum(displacement)
position.ext=extrema(position)
}
#unused
- firstDownPhaseTime = position.ext$minindex[1]
- downHeight = abs(position[1] - position[firstDownPhaseTime])
+ #firstDownPhaseTime = position.ext$minindex[1]
+ #downHeight = abs(position[1] - position[firstDownPhaseTime])
}
- positionPerson = abs(cumsum(displacement))*-1
+ positionPerson = cumsum(displacement)
+ positionPerson = positionPerson + positionStart
+ positionPerson = abs(positionPerson)*-1
+
#this is to make "inverted cumsum"
+ #this displacement when 'cumsum' into position is the reality,
+ #but if we use it it will seem a VERY high acceleration in the beginning (between the fist and second
value)
+ #because it will be: eg: -1100, 0, 0, 0, 0, 1, ...
+ #don't use it
+ #displacementPerson = c(positionStart,diff(positionPerson))
+ #better have it starting with 0 and then speed calculations... will be correct
displacementPerson = c(0,diff(positionPerson))
#write(displacementPerson,stderr())
diff --git a/src/gui/encoder.cs b/src/gui/encoder.cs
index f7182bc..e5c4b18 100644
--- a/src/gui/encoder.cs
+++ b/src/gui/encoder.cs
@@ -1326,8 +1326,8 @@ public partial class ChronoJumpWindow
//test: try to compress signal in order to send if.
//obviously this is not going to be done here
- LogB.Information("Trying compress function");
- LogB.Information(UtilEncoder.CompressSignal(UtilEncoder.GetEncoderDataTempFileName()));
+ //LogB.Information("Trying compress function");
+ //LogB.Information(UtilEncoder.CompressSignal(UtilEncoder.GetEncoderDataTempFileName()));
if(success) {
//force a recalculate but not save the curve (we are loading)
@@ -2245,21 +2245,55 @@ public partial class ChronoJumpWindow
//1) check heightCurve in a fast way first to
discard curves soon
// only process curves with height >=
min_height
- //2) if it's concentric, only take the
concentric curves
+ //2) if it's concentric, only take the
concentric curves,
+ // but if it's concentric and inertial:
take both.
+ //
+ // When capturing on inertial, we have the
first graph
+ // that will be converted to the second.
+ // we need the eccentric phase in order to
detect the Ci2
+
+ /*
+ * /\
+ * / \
+ * / \
+ *____ C1 \ ___
+ * \ / \ /
+ * \ / \ C2
+ * \/ \/
+ *
+ * C1, C2: two concentric phases
+ */
+
+ /*
+ *____ ___
+ * \ /\ /\ /
+ * \ Ci1 \ Ci2 \ Ci3
+ * \/ \ / \/
+ * \/
+ *
+ * Ci1, Ci2, Ci3: three concentric phases on
inertial
+ */
+
//3) if it's ecc-con, don't record first
curve if first curve is concentric
+
+ //TODO: needs tweaking on inertia ecc-con at
first curve
if(
heightCurve >=
encoderSelectedMinimumHeight && //1
- ( ( eccon == "c" &&
previousWasUp ) || eccon != "c" ) && //2
+ (
+ ( eccon == "c" && ecc.up )
|| //2) "c" and going up
+ (
+ eccon == "c" &&
//2) or "c" and inertial but not first eccentric phase
+
encoderConfigurationCurrent.has_inertia &&
+ ! ( ! ecc.up &&
ecca.curvesAccepted == 0 )
+ ) ||
+ eccon != "c"
//2) or !"c"
+ ) &&
! ( (eccon == "ec" || eccon
== "ecS") && ecc.up && ecca.curvesAccepted == 0 ) //3
) {
- //this is need on inertial to convert
on direction curve (recorded by encoder)
- //to a con-ecc curve (done by the
person)
-
if(encoderConfigurationCurrent.has_inertia)
- curve[0] =
heightAtCurveStart;
UtilEncoder.RunEncoderCaptureNoRDotNetSendCurve(
- pCaptureNoRDotNet,
curve);
+ pCaptureNoRDotNet,
heightAtCurveStart, curve);
ecca.curvesDone ++;
ecca.curvesAccepted ++;
ecca.ecc.Add(ecc);
diff --git a/src/utilEncoder.cs b/src/utilEncoder.cs
index d4055e9..46cdafb 100644
--- a/src/utilEncoder.cs
+++ b/src/utilEncoder.cs
@@ -474,15 +474,22 @@ public class UtilEncoder
- public static void RunEncoderCaptureNoRDotNetSendCurve(Process p, double [] d)
+ public static void RunEncoderCaptureNoRDotNetSendCurve(Process p, double heightAtStart, double [] d)
{
- LogB.Debug("writing line 1");
- string curveSend = string.Join(" ", Array.ConvertAll(d, x => x.ToString()));
+ LogB.Debug("writing line 1 -->");
+
+ string curveSend = "ps " + Util.ConvertToPoint(heightAtStart);
+ LogB.Debug("curveSend [heightAtStart]",curveSend);
+ p.StandardInput.WriteLine(curveSend);
+
+ curveSend = string.Join(" ", Array.ConvertAll(d, x => x.ToString()));
//TODO convert comma to point in this doubles
- LogB.Debug("curveSend",curveSend);
+ LogB.Debug("curveSend [displacement array]",curveSend);
p.StandardInput.WriteLine(curveSend);
+
+ LogB.Debug("<-- writen line 1");
}
public static void RunEncoderCaptureNoRDotNetSendEnd(Process p)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]