[chronojump] run interval with double contacts painting chunks working at speedStart leaving
- From: Xavier de Blas <xaviblas src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [chronojump] run interval with double contacts painting chunks working at speedStart leaving
- Date: Fri, 20 Apr 2018 22:51:09 +0000 (UTC)
commit b08b019245c396af573b9e5ba03a89ef6902cc78
Author: Xavier de Blas <xaviblas gmail com>
Date: Sat Apr 21 00:49:20 2018 +0200
run interval with double contacts painting chunks working at speedStart leaving
src/execute/run.cs | 2 +-
src/execute/runObjects.cs | 299 ++++++++++++++++++++++++++++-----------------
src/gui/eventExecute.cs | 56 ++++++---
3 files changed, 226 insertions(+), 131 deletions(-)
---
diff --git a/src/execute/run.cs b/src/execute/run.cs
index 5473e24..3f00cb4 100644
--- a/src/execute/run.cs
+++ b/src/execute/run.cs
@@ -244,7 +244,7 @@ public class RunExecute : EventExecute
checkDoubleContactTime,
speedStartArrival
);
- runPTL = new RunPhaseTimeList();
+ runPTL = new RunPhaseTimeList(checkDoubleContactTime);
bool firstFromChronopicReceived = false;
bool exitWaitEventBucle = false;
diff --git a/src/execute/runObjects.cs b/src/execute/runObjects.cs
index a1d1f10..5c33778 100644
--- a/src/execute/runObjects.cs
+++ b/src/execute/runObjects.cs
@@ -59,13 +59,16 @@ public class RunPhaseInfoManage
{
public bool TrackDoneHasToBeCalledAgain;
private List<RunPhaseInfo> list;
+ private int checkTime;
//TCs and TFs before startPos have been added as tracks
//do not count again in track operations
private int startPos;
- public RunPhaseInfoManage ()
+ public RunPhaseInfoManage (int checkTime)
{
+ this.checkTime = checkTime;
+
list = new List<RunPhaseInfo>();
startPos = 0;
TrackDoneHasToBeCalledAgain = false;
@@ -88,7 +91,7 @@ public class RunPhaseInfoManage
* check first TF if exists or all TC+TF pairs to see if all are lower than checkTime (eg 300ms)
* return true if all are <= checkTime
*/
- public bool IsStartDoubleContact(int checkTime)
+ public bool IsStartDoubleContact()
{
LogB.Information("At rpim IsStartDoubleContact A");
int startAt = 0;
@@ -124,74 +127,55 @@ public class RunPhaseInfoManage
return true;
}
- /*
- * check double contacts at start:
- * if ! speedStart: start at contact first contact will be TF (race starts at beginning)
- * if speedStart: start before contact (race starts related to biggest_TC
- * if(speedStartArrival) first contact will be TC (start at beginning of biggest_TC)
- * else first contact will be TF (start at end of biggest_TC)
- */
- /*
- * aixo sera la funciĆ³ start double contact position()
- * maybe not used because GetPosOfBiggestTC will be recicled
- *
- *
- //return the double contact tc+tf at beginning
- if(! speedStart)
- return 0;
+ private int findTracksInThisChunk(int forStartPos)
+ {
+ int tracks = 0;
+ RunPhaseInfo firstRPI = (RunPhaseInfo) list[0];
+ if(! firstRPI.IsContact())
+ forStartPos ++;
- //--- from now on speedStart
+ //i will be tf, i-1 will be tc
+ for(int i = forStartPos + 1; i < list.Count; i += 2)
+ {
+ RunPhaseInfo tcRPI = (RunPhaseInfo) list[i-1];
+ RunPhaseInfo tfRPI = (RunPhaseInfo) list[i];
- //bool first = true;
- int startAt = 0;
+ if(tcRPI.Duration + tfRPI.Duration > checkTime)
+ tracks ++;
+ }
- double maxTCDuration = 0;
- int maxTCPosition = 0;
- bool speedStartArrival = true;
+ return tracks;
+ }
- if(list.Count > 0)
- {
- RunPhaseInfo firstRPI = (RunPhaseInfo) list[0];
- if(! firstRPI.IsContact()) //is TF
- {
- speedStartArrival = false;
- if (firstRPI.Duration < checkTime)
- startAt = 1;
- else
- return 0;
- }
- }
+ //find the position of the first big tf of the chunk
+ private int findTfPosOfChunk(int forStartPos)
+ {
+ RunPhaseInfo firstRPI = (RunPhaseInfo) list[0];
+ if(! firstRPI.IsContact())
+ forStartPos ++;
- RunPhaseInfo tcRPI;
- RunPhaseInfo tfRPI;
- for(int i = startAt +1; i < list.Count; i +=2)
+ //i will be tf, i-1 will be tc
+ int i;
+ for(i = forStartPos + 1; i < list.Count; i += 2)
{
- tcRPI = (RunPhaseInfo) list[i-1];
- tfRPI = (RunPhaseInfo) list[i];
-
- if(tcRPI.Duration > maxTCDuration)
- {
- maxTCDuration = tcRPI.Duration;
- maxTCPosition = i;
- }
+ RunPhaseInfo tcRPI = (RunPhaseInfo) list[i-1];
+ RunPhaseInfo tfRPI = (RunPhaseInfo) list[i];
- if(tcRPI.Duration + tfRPI.Duration >= checkTime)
+ LogB.Information(string.Format("at findTfPosOfChunk: i:{0}, tc:{1}, tf:{2}",
+ i, tcRPI, tfRPI));
+ if(tcRPI.Duration + tfRPI.Duration > checkTime)
{
- if(speedStartArrival)
- return maxTCPosition -1;
- else
- return maxTCPosition;
+ LogB.Information("YES!");
+ return i;
}
}
- if(speedStartArrival)
- return maxTCPosition -1;
- else
- return maxTCPosition;
+ //we are supposed to not arrive here
+ return forStartPos;
}
- */
- public int GetPosOfBiggestTC (bool started, int checkTime)
+
+ public int GetPosOfBiggestTC (bool started)
{
LogB.Information("startPos at GetPosOfBiggestTC: " + startPos.ToString());
TrackDoneHasToBeCalledAgain = false;
@@ -201,58 +185,74 @@ public class RunPhaseInfoManage
return startPos +1;
double max = 0;
- int pos = 0;
int posBiggest = 0;
double lastTcDuration = 0;
- foreach(RunPhaseInfo rpi in list)
+ /*
+ * first time we need to know if first TC is greater than the others
+ * but once started, we care for endings of each track,
+ * do not use the first value because it's the TC of previous track
+ */
+ int forStartPos;
+ if(started)
+ forStartPos = startPos +1;
+ else
+ forStartPos = startPos;
+
+ LogB.Information("forStartPos A: " + forStartPos.ToString());
+
+ int tracks = findTracksInThisChunk(forStartPos);
+ LogB.Information("findTracksInThisChunk tracks: " + tracks.ToString());
+
+ //on track starts, maybe there are some tc+tf pairs before the big tf
+ //A is the track start
+ //B is the big tf, we should find biggest tc after this tf
+ // A __ ___B __ ___
+ if(tracks >= 1)
{
- /*
- * first time we need to know if first TC is greater than the others
- * but once started, we care for endings of each track,
- * do not use the first value because it's the TC of previous track
- */
- if( (started && pos >= startPos +1) || (! started && pos >= startPos) )
- {
- /*
- * record tc duration as lastTcDuration and add to td duration to see if is
greater than checktime
- * this allows to return biggest_tc of one track without messing with next
track that maybe is captured
- * this happens because double contacts is eg: 300 and trackDone is calle at
300 * 1,5
- * But then trackDone has to be called again!
- */
- if(rpi.IsContact())
- lastTcDuration = rpi.Duration;
- else if(! rpi.IsContact() && lastTcDuration + rpi.Duration > checkTime)
- {
- //check if there's another track in this set
- for(int i = pos + 2; i < list.Count; i += 2)
- {
- RunPhaseInfo tcRPI = (RunPhaseInfo) list[i-1];
- RunPhaseInfo tfRPI = (RunPhaseInfo) list[i];
+ forStartPos = findTfPosOfChunk(forStartPos);
+ //note forStartPos has changed and following findTfPosOfChunk will start from this tf
+ }
- if(tcRPI.Duration + tfRPI.Duration > checkTime)
- TrackDoneHasToBeCalledAgain = true;
- }
+ LogB.Information("forStartPos B: " + forStartPos.ToString());
- return posBiggest;
- }
+ //this will be the pos of the tf of second Track if exists
+ int forEnds = list.Count;
+ if(tracks >= 2)
+ {
+ forEnds = findTfPosOfChunk(forStartPos);
+ TrackDoneHasToBeCalledAgain = true;
+ }
- //record posBiggest position
- if(rpi.IsContact() && rpi.Duration > max)
- {
- max = rpi.Duration;
- posBiggest = pos;
- }
- }
+ LogB.Information("forEnds: " + forEnds.ToString());
- pos ++;
+ for(int pos = forStartPos; pos < forEnds; pos ++)
+ {
+ RunPhaseInfo rpi = (RunPhaseInfo) list[pos];
+
+ LogB.Information("rpi: " + rpi.ToString());
+ /*
+ * record tc duration as lastTcDuration and add to tf duration to see if is greater
than checktime
+ * this allows to return biggest_tc of one track without messing with next track that
maybe is captured
+ * this happens because double contacts is eg: 300 and trackDone is calle at 300 * 1,5
+ * But then trackDone has to be called again!
+ */
+ if(rpi.IsContact())
+ lastTcDuration = rpi.Duration;
+
+ //record posBiggest position
+ if(rpi.IsContact() && rpi.Duration > max)
+ {
+ max = rpi.Duration;
+ posBiggest = pos;
+ }
}
+
return posBiggest;
}
//if pos == -1 return all
public double SumUntilPos(int pos, bool firstTrackDone, bool speedStartArrival)
- //public double SumUntilPos(int pos)
{
LogB.Information(string.Format("SumUntilPos: startAt: {0}, until pos: {1}, firstTrackDone:
{2}, speedStartArrival: {3}",
startPos, pos, firstTrackDone, speedStartArrival));
@@ -383,7 +383,7 @@ public class RunDoubleContact
lastTc = 0;
timeAcumulated = 0;
- rpim = new RunPhaseInfoManage();
+ rpim = new RunPhaseInfoManage(checkTime);
listCaptureThread = new List<RunPhaseInfo>();
FirstTrackDone = false;
TrackDoneHasToBeCalledAgain = false;
@@ -441,14 +441,14 @@ public class RunDoubleContact
LogB.Information("At RunDC IsStartDoubleContact");
//return rpim.IsStartDoubleContact(checkTime);
- bool isDC = rpim.IsStartDoubleContact(checkTime);
+ bool isDC = rpim.IsStartDoubleContact();
LogB.Information("IsStartDoubleContact: " + isDC.ToString());
return isDC;
}
public int GetPosOfBiggestTC(bool started)
{
- int pos = rpim.GetPosOfBiggestTC(started, checkTime);
+ int pos = rpim.GetPosOfBiggestTC(started);
if(rpim.TrackDoneHasToBeCalledAgain)
{
@@ -456,7 +456,7 @@ public class RunDoubleContact
//rpim.TrackDoneHasToBeCalledAgain = false;
}
- LogB.Information(string.Format("GetPosOfBiggestTC list: {0}, pos: {1}, hasToBeCaledAgain:
{2}",
+ LogB.Information(string.Format("GetPosOfBiggestTC list: {0}, pos: {1}, hasToBeCalledAgain:
{2}",
rpim.PrintList(), pos, TrackDoneHasToBeCalledAgain));
return pos;
@@ -512,12 +512,15 @@ public class RunDoubleContact
public class RunPhaseTimeList
{
private List<PhaseTime> listPhaseTime;
+ private int checkTime;
//if there are double contacts at start, first run phase infos will not be used
public int FirstRPIs;
- public RunPhaseTimeList()
+ public RunPhaseTimeList(int checkTime)
{
+ this.checkTime = checkTime;
+
listPhaseTime = new List<PhaseTime>();
FirstRPIs = 0;
}
@@ -546,9 +549,9 @@ public class RunPhaseTimeList
return str;
}
- public List<string> InListForPainting()
+ public List<RunPhaseTimeListObject> InListForPainting()
{
- List<string> list_in = new List<string>();
+ List<RunPhaseTimeListObject> list_in = new List<RunPhaseTimeListObject>();
int currentMS = 0;
int startInMS = -1;
@@ -580,6 +583,10 @@ public class RunPhaseTimeList
int count = 0;
double negativeValues = 0; //double contacts times at start
PhaseTime ptLast = null;
+
+ RunPhaseTimeListObject.Phases currentPhase = RunPhaseTimeListObject.Phases.START;
+ RunPhaseTimeListObject rptloToAdd = null;
+
foreach(PhaseTime pt in listPhaseTimeShallowCloned)
{
LogB.Information(pt.ToString());
@@ -593,7 +600,30 @@ public class RunPhaseTimeList
if(pt.IsContact)
startInMS = currentMS;
else if(startInMS >= 0)
- list_in.Add(startInMS/1000.0 + ":" + currentMS/1000.0); //in seconds
+ {
+ //see if previous has ended to mark as END or STARTEND
+ if(rptloToAdd != null)
+ {
+ if(startInMS/1000.0 - rptloToAdd.tcStart > checkTime/1000.0)
+ {
+ if(rptloToAdd.phase == RunPhaseTimeListObject.Phases.START)
+ rptloToAdd.phase =
RunPhaseTimeListObject.Phases.STARTANDEND;
+ else
+ rptloToAdd.phase = RunPhaseTimeListObject.Phases.END;
+
+ currentPhase = RunPhaseTimeListObject.Phases.START;
+ } else
+ currentPhase = RunPhaseTimeListObject.Phases.MIDDLE;
+
+ list_in.Add(rptloToAdd);
+ }
+
+ //this will be added in next iteration of flight (! pt.IsContact)
+ rptloToAdd = new RunPhaseTimeListObject(
+ currentPhase,
+ startInMS/1000.0,
+ currentMS/1000.0);
+ }
currentMS += Convert.ToInt32(pt.Duration);
@@ -604,10 +634,30 @@ public class RunPhaseTimeList
count ++;
}
+ //add pending rptl
+ if(startInMS/1000.0 - rptloToAdd.tcStart > checkTime/1000.0)
+ {
+ if(rptloToAdd.phase == RunPhaseTimeListObject.Phases.START)
+ rptloToAdd.phase = RunPhaseTimeListObject.Phases.STARTANDEND;
+ else
+ rptloToAdd.phase = RunPhaseTimeListObject.Phases.END;
+ }
+
+ list_in.Add(rptloToAdd);
+
//when track ends, last phase is a TC, add it
if(ptLast != null && ptLast.IsContact)
- list_in.Add( startInMS/1000.0 + ":" +
- (startInMS + ptLast.Duration)/1000.0); //in seconds
+ {
+ RunPhaseTimeListObject rptloLast = new RunPhaseTimeListObject(
+ RunPhaseTimeListObject.Phases.END,
+ startInMS/1000.0,
+ (startInMS + ptLast.Duration)/1000.0);
+
+ if(rptloToAdd.phase == RunPhaseTimeListObject.Phases.START)
+ rptloLast.phase = RunPhaseTimeListObject.Phases.STARTANDEND;
+
+ list_in.Add(rptloLast);
+ }
//manage the negative values
if(negativeValues > 0)
@@ -617,11 +667,10 @@ public class RunPhaseTimeList
{
LogB.Information(string.Format("PRE i: {0}, list_in[{0}]: {1}", i,
list_in[i]));
- string [] strFull = list_in[i].Split(new char[] {':'});
- list_in[i] = (Convert.ToDouble(strFull[0]) - negativeValues).ToString() + ":"
+
- (Convert.ToDouble(strFull[1]) - negativeValues).ToString();
-
- LogB.Information(string.Format("POST i: {0}, list_in[{0}]: {1}", i,
list_in[i]));
+ RunPhaseTimeListObject rptlo = (RunPhaseTimeListObject) list_in[i];
+ rptlo.tcStart -= negativeValues;
+ rptlo.tcEnd -= negativeValues;
+ list_in[i] = rptlo;
}
}
@@ -632,15 +681,39 @@ public class RunPhaseTimeList
public string InListForPaintingToString()
{
string str = "Contact in time list:\n";
- List<string> list_in = InListForPainting();
- foreach(string s in list_in)
- str += s + "\n";
+ List<RunPhaseTimeListObject> list_in = InListForPainting();
+ foreach(RunPhaseTimeListObject rptlo in list_in)
+ str += rptlo.ToString() + "\n";
return str;
}
}
+public class RunPhaseTimeListObject
+{
+ //each contact can be start of a chunk, middle, end or startandend
+ //this is important for the drawing in gui/eventExecute.cs
+ public enum Phases { START, MIDDLE, END, STARTANDEND }
+ public Phases phase;
+ public double tcStart;
+ public double tcEnd;
+
+ public RunPhaseTimeListObject (Phases phase, double tcStart, double tcEnd)
+ {
+ this.phase = phase;
+ this.tcStart = tcStart;
+ this.tcEnd = tcEnd;
+ }
+
+ public override string ToString()
+ {
+ return phase.ToString() + ":" +
+ Math.Round(tcStart, 3).ToString() + ":" +
+ Math.Round(tcEnd, 3).ToString();
+ }
+}
+
//currently used for simple runs
public class RunExecuteInspector
{
diff --git a/src/gui/eventExecute.cs b/src/gui/eventExecute.cs
index 7847f5b..55d7e51 100644
--- a/src/gui/eventExecute.cs
+++ b/src/gui/eventExecute.cs
@@ -1468,18 +1468,17 @@ public partial class ChronoJumpWindow
double negativePTLTime = 0; //negativePTL at beginning and last TC at end
double timeTotalWithExtraPTL = timeTotal;
- List<string> runPTLInListForPainting = runPTL.InListForPainting();
+ List<RunPhaseTimeListObject> runPTLInListForPainting = runPTL.InListForPainting();
if(runPTLInListForPainting.Count > 0)
{
//last TC value
- string [] inPTLLastFull =
runPTLInListForPainting[runPTLInListForPainting.Count -1].Split(new char[] {':'});
- double lastValue = Convert.ToDouble(inPTLLastFull[1]);
+ RunPhaseTimeListObject rptlfp = (RunPhaseTimeListObject)
runPTLInListForPainting[runPTLInListForPainting.Count -1];
+ timeTotalWithExtraPTL = rptlfp.tcEnd;
- timeTotalWithExtraPTL = lastValue;
//negative values
- string [] inPTL0Full = runPTLInListForPainting[0].Split(new char[] {':'});
- double firstValue = Convert.ToDouble(inPTL0Full[0]);
+ rptlfp = (RunPhaseTimeListObject) runPTLInListForPainting[0];
+ double firstValue = rptlfp.tcStart;
if(firstValue < 0)
{
@@ -1493,8 +1492,10 @@ public partial class ChronoJumpWindow
//paint reference guide black and green if needed
- drawGuideOrAVG(pen_black_discont, eventGraphConfigureWin.BlackGuide, alto, ancho,
topMargin, bottomMargin, maxValue, minValue, guideWidthEnum.FULL);
- drawGuideOrAVG(pen_green_discont, eventGraphConfigureWin.GreenGuide, alto, ancho,
topMargin, bottomMargin, maxValue, minValue, guideWidthEnum.FULL);
+ drawGuideOrAVG(pen_black_discont, eventGraphConfigureWin.BlackGuide,
+ alto, ancho, topMargin, bottomMargin, maxValue, minValue,
guideWidthEnum.FULL);
+ drawGuideOrAVG(pen_green_discont, eventGraphConfigureWin.GreenGuide,
+ alto, ancho, topMargin, bottomMargin, maxValue, minValue,
guideWidthEnum.FULL);
string [] myTimesStringFull = timesString.Split(new char[] {'='});
int count = 0;
@@ -1505,21 +1506,42 @@ public partial class ChronoJumpWindow
Gdk.GC myPen = pen_rojo; //default value
double myValue = 0;
+ int lastChunkStart = 0;
+ int chunkMargins = 4;
- foreach (string inPTL in runPTL.InListForPainting())
- //foreach (string inPTL in runPTLInListForPainting)
+ foreach (RunPhaseTimeListObject inPTL in runPTL.InListForPainting())
{
- string [] inPTLFull = inPTL.Split(new char[] {':'});
int xStart = event_execute_rightMargin + Convert.ToInt32((ancho -
2*event_execute_rightMargin) *
- (Convert.ToDouble(inPTLFull[0]) + negativePTLTime) /
timeTotalWithExtraPTL);
+ (inPTL.tcStart + negativePTLTime) /
timeTotalWithExtraPTL);
int xEnd = event_execute_rightMargin + Convert.ToInt32((ancho -
2*event_execute_rightMargin) *
- (Convert.ToDouble(inPTLFull[1]) + negativePTLTime) /
timeTotalWithExtraPTL);
+ (inPTL.tcEnd + negativePTLTime) / timeTotalWithExtraPTL);
+
+ event_execute_pixmap.DrawRectangle(pen_gris, true,
+ new Rectangle (xStart, alto-bottomMargin-4, xEnd-xStart, 4));
+
+ //manage chunks indications
+ if(inPTL.phase == RunPhaseTimeListObject.Phases.START)
+ {
+ //draw the vertical start line
+ event_execute_pixmap.DrawLine(pen_gris,
+ xStart - chunkMargins, alto-bottomMargin -4,
+ xStart - chunkMargins, alto-bottomMargin -(4 +
chunkMargins));
+ lastChunkStart = xStart;
+ }
+ else if(inPTL.phase == RunPhaseTimeListObject.Phases.END)
+ {
+ //draw the vertical end line
+ event_execute_pixmap.DrawLine(pen_gris,
+ xEnd + chunkMargins, alto-bottomMargin -4,
+ xEnd + chunkMargins, alto-bottomMargin -(4 +
chunkMargins));
+
+ //draw the horizontal start-end line
+ event_execute_pixmap.DrawLine(pen_gris,
+ lastChunkStart - chunkMargins, alto-bottomMargin -(4
+ chunkMargins),
+ xEnd + chunkMargins, alto-bottomMargin -(4 +
chunkMargins));
+ }
- //don't plot the TCs after current track
- //if(Convert.ToDouble(inPTLFull[0]) + negativePTLTime < timeTotalWithExtraPTL)
- event_execute_pixmap.DrawRectangle(pen_gris, true,
- new Rectangle (xStart, alto-bottomMargin-4,
xEnd-xStart, 4));
}
foreach (string myTime in myTimesStringFull)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]