PredictUserContext *u= c->u;
oprintf(DUPO("safety") " predict %s"
- " %s%s dist=%-4d until=%-4ld %c%c%c.%c (was %s%s dist=%-4d)"
+ " %s%s dist=%-4d until=%-4ld %c%c%c.%c (was %s%s..%d dist=%-4d)"
" %c%c%c%c.%c%c%c%c"
" elapsed=%ld nit=%d,%d\n",
what,
before && before->backwards?"-":"",
before ? before->seg->i->pname : "-",
+ before ? before->remain : -1,
+
u->was_distance,
"-t"[ u->count_time ],
TimeInterval max_ms;
ErrorCode ec;
- if (!before) return 0;
pred_callback_debug(" nose_nextseg",t,c,before);
+ if (!before) return 0;
if (u->optimistic)
advance_elapsed(u,calc_advanced(c));
MovPosComb *mpc_io, const TrackLocation *before) {
PredictUserContext *u= c->u;
- if (!before) return 0;
pred_callback_debug(" tail_nextseg",t,c,before);
+ if (!before) return 0;
if (!before->seg->i->invertible)
u->noninv_tally[before->backwards]--;
* the previous segment.
*/
- if (!before) return 0;
pred_callback_debug("fdet_nextseg",t,c,before);
+ if (!before) return 0;
advanced= calc_advanced(c);
u.problem_callback= ppc;
u.problem_callback_u= ppcu;
u.maxspeed= speedmanager_speed_maxestimate(u.train);
+ u.stopping= speedmanager_stopping(u.train);
u.stopping_distance= speedmanager_stoppingdistance(u.train);
- u.stopping= !accelerate && speedmanager_stopping(u.train);
- oprintf(DUPO("safety") " predict starting %s%s maxspeed=%f"
- " (speed %f try %f, step %d%s) stopdist=%d%s%s\n",
+ switch (accelerate) {
+ case 1: u.stopping= 0; break;
+ case 0: break;
+ case -1: if (u.stopping) u.stopping_distance -= tra->uncertainty; break;
+ default: abort();
+ }
+
+ oprintf(DUPO("safety") " predict ***starting*** %s%s maxspeed=%f"
+ " (speed %f try %f, step %d%s) stopdist=%d accelerate=%d %s\n",
tra->backwards?"-":"",tra->pname,
u.maxspeed, tra->speed.speed, tra->speed.try_speed, tra->speed.step,
tra->speed.decel.running ? " decel" : "",
u.stopping_distance,
- accelerate ? " accel" : "",
+ accelerate,
u.stopping ? " stopping" : "");
FOR_SEG {
if (!foredet)
return predict_problem(&u,0,"train is not on layout");
- u.accelerating= accelerate;
u.walk_compute_polarise= 1;
u.train_polarity_inverted= foredet->seg_inverted ^ foredet->tr_backwards;
u.usecurrentposn= 1;
tra->uncertainty= tra->maxinto= stopdist;
report_train_position(tra);
- ec= predict(tra, 0, detection_report_problem, 0);
+ ec= predict(tra,-1, detection_report_problem, 0);
if (!ec) return;
assert(ec == EC_SignallingPredictedProblem);
- if (tra->maxinto > stopdist) {
- tra->uncertainty= tra->maxinto= stopdist;
- report_train_position(tra);
- }
+ if (maxinto > stopdist) maxinto= stopdist;
+ tra->maxinto= tra->uncertainty= maxinto;
report_train_position(tra);
+ speedmanager_safety_stop(tra);
+ ec= predict(tra,-1, 0,(char*)"safety commanding stop");
+ assert(!ec);
- ec= speedmanager_speedchange_request(tra,0, 0,(char*)"detection sigstop");
- /* that calls predict_confirm with our supplied arguments */
assert(!ec);
}
* Caller must call this with different situations until it succeeds!
* Caller may pass ppc=0 and ppcu=(char*)"some context" to
* cause safety_panic if it fails.
+ *
+ * accelerate should be:
+ * -1 if we have just detected the train entering its foredetect
+ * so we can subtract the uncertainty from the stopping distance
+ * 0 if whatever we are doing will not disturb the existing plan
+ * 1 if we the existing plan is not necessarily sufficient as
+ * we are intending to accelerate or something
*/
void report_train_position(Train *tra);
PredictionProblemCallback *ppc, void *ppcu);
/* ppc and ppcu as for predict_confirm */
+void speedmanager_safety_stop(Train *tra);
void speedmanager_reset_train(Train *tra);
double speedmanager_speed_maxestimate(Train *tra);
double speedmanager_stoppingdistance(Train *tra);
typedef struct TrackLocation TrackLocation;
struct TrackLocation { /* transparent, and manipulable by trackloc_... fns */
Segment *seg; /* current segment */
- long remain; /* distance from end of segment as we look at it */
+ Distance remain; /* distance from end of segment as we look at it */
unsigned backwards:1; /* if 1, into is positive and measured from end */
};
return r;
}
-ErrorCode speedmanager_speedchange_request(Train *tra, int step,
- PredictionProblemCallback *ppc, void *ppcu) {
+static ErrorCode request_core(Train *tra, int step,
+ PredictionProblemCallback *ppc, void *ppcu) {
ErrorCode ec, ec2;
struct timeval tnow;
double vnow, vtarg;
tra->speed.decel.duration= stop_info(tra,vnow)->ts;
toev_start(&tra->speed.decel);
tra->speed.speed= vnow;
- ec= predict(tra,0, 0,(char*)"deceleration forbidden");
- assert(!ec);
+ if (ppc || ppcu) {
+ ec= predict(tra,0, 0,(char*)"deceleration forbidden");
+ assert(!ec);
+ }
xmit(tra);
return 0;
}
return 0;
}
+ErrorCode speedmanager_speedchange_request(Train *tra, int step,
+ PredictionProblemCallback *ppc, void *ppcu) {
+ assert(ppc || ppcu);
+ return request_core(tra,step,ppc,ppcu);
+}
+
+void speedmanager_safety_stop(Train *tra) {
+ ErrorCode ec;
+ ec= request_core(tra,0,0,0);
+ assert(!ec);
+}
+
void speedmanager_reset_train(Train *tra) {
Nmra n;