* using the foredetect; when it enters a new segment we advance first
* the head and then the tail by the same distance.
*
- * We advance foredetect firstly exactly one segment and then over the
- * current stopping distance. At each advancement we record the time
- * from the currently-next detection at which this prediction will
- * happen (computed from the current speed). (We don't take into
- * account any already commanded but not necessarily happened
- * deceleration; however if we are attempting to increase our speed,
- * current speed refers to the new speed.) If we're already stopping
- * then we advance by the stopping distance only (since we don't need
- * to worry about not being told to stop until the next detection);
- * also we stop advancing when we run out of segments we own (this
- * deals with segment-sized rounding errors which might otherwise
- * make us think we will overrun).
+ * We advance foredetect by the total of the uncertainty (which takes
+ * it into the next segment) and the current stopping distance. At
+ * each advancement we record the earliest time from now at which this
+ * prediction will happen (computed from the current speed). (We
+ * don't take into account any already commanded but not necessarily
+ * happened deceleration; however if we are attempting to increase our
+ * speed, current speed refers to the new speed.) If we're already
+ * stopping then we advance by the stopping distance only (since we
+ * don't need to worry about not being told to stop until the next
+ * detection); also we stop advancing when we run out of segments we
+ * own (this deals with segment-sized rounding errors which might
+ * otherwise make us think we will overrun).
*
* At each new track location for our front end we hope to find a
* segment which no-one currently owns and which is currently set for
* movfeat changes.
*
* If not then we issue an signal stop command (we'd better not be
- * doing that already!) or countermand the speed increase or whatever. */
+ * doing that already!) or countermand the speed increase or whatever.
+ */
/*
* Here is how we use the stuff in the Segment:
*
accelerating:1,
stopping:1,
done_first_new_fdet:1,
- count_time:1,
usecurrentposn:1, /* for pred_getmovpos */
optimistic:1, /* for autopoint */
walk_compute_polarise:1, /* nose_nextseg still needs to worry */
oprintf(DUPO("safety") " predict %s"
" %c%s dist=%-4d until=%-4ld %c%c%c.%c (was %s%s..%d dist=%-4d)"
- " %c%c%c%c.%c%c%c%c"
+ " %c%c%c.%c%c%c%c"
" elapsed=%ld nit=%d,%d\n",
what,
u->was_distance,
"-2"[ u->done_first_new_fdet ],
- "-t"[ u->count_time ],
"-c"[ u->usecurrentposn ],
"-o"[ u->optimistic ],
goto movement_ok;
}
/* We have a plan but it involves some motion: */
+ if (u->elapsed < 0)
+ return predict_problem(u, t->seg, "arrived but route not set");
if (t->seg->pred_vacated) {
if (!t->seg->now_present)
/* And we're not even there yet! This is too hard because we
if (!t->seg->pred_vacated)
t->seg->tr_backwards= t->backwards;
t->seg->pred_present= 1;
- t->seg->until= u->elapsed;
+ t->seg->until= u->elapsed < 0 ? 0 : u->elapsed;
return 0; /* yay! */
}
if (before->seg->pred_vacated) return 0; /* only vacate once */
before->seg->pred_present= 0;
before->seg->pred_vacated= 1;
- before->seg->until= u->elapsed;
+ before->seg->until= u->elapsed < 0 ? 0 : u->elapsed;
return 0;
}
if (!before) return 0;
advanced= calc_advanced(c);
-
- if (u->count_time)
- advance_elapsed(u,advanced);
+ advance_elapsed(u,advanced);
u->nosec.distance= advanced;
r= trackloc_advance(&u->nose,&u->nosec);
/* Final adjustments, prepare for next iteration */
u->was_distance= c->distance;
- u->count_time= 1; /* we start counting time only after we've done the
- * whole foredetect segment as we may already have
- * nearly finished it */
return 0;
}
u.nosec.nextseg= nose_nextseg;
u.nosec.trackend= pred_trackend;
u.nosec.distance= nose_length(tra);
- u.count_time= 0;
u.nose= u.fdet;
u.fdetc.distance= u.stopping_distance;
} else {
u.fdetc.distance= tra->uncertainty + u.stopping_distance;
+ u.elapsed= -tra->uncertainty / u.maxspeed;
}
u.fdetc.distance += MARGIN_NOSE;
u.was_distance= u.fdetc.distance;