From 95ea460c2f50582191417f73a10cb87072991ea1 Mon Sep 17 00:00:00 2001 From: ian Date: Mon, 5 May 2008 12:58:42 +0000 Subject: [PATCH] when train is stopping, do not advance to next segment detection first, and remain within stopping distance of next detected segment --- hostside/TODO | 9 +++++++ hostside/safety.c | 66 +++++++++++++++++++++++++++++------------------ 2 files changed, 50 insertions(+), 25 deletions(-) diff --git a/hostside/TODO b/hostside/TODO index 4859f14..e9b189b 100644 --- a/hostside/TODO +++ b/hostside/TODO @@ -1,3 +1,12 @@ + +two bugs in current sim log + - realtime: fatal: fatal signalling problem: shinkansen at A6: unexpected problem predicted (context: deceleration forbidden): cannot set track polarity + + - train shinkansen has -X9. -A5/P1. -A3. -A1. X2. X4. X8/P1.! X10* A6/P0 A5/P1. X9. +wtf at speed 30 ?? + + + bugs does not set serial port mode etc. diff --git a/hostside/safety.c b/hostside/safety.c index 803512e..851ed8a 100644 --- a/hostside/safety.c +++ b/hostside/safety.c @@ -41,9 +41,12 @@ Segment *segments; * 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 emergency - * stopping then we ignore the stopping distance and instead keep - * advancing until we run out of segments we own. + * 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 @@ -95,8 +98,7 @@ Segment *segments; * 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: * @@ -193,7 +195,7 @@ Segment *segments; * adv. fdet 1 seg T N F * adv. nose T F N * adv. tail T F N - * adv. fdet stopdist T N F N + * adv. fdet stopdist T N F * adv. nose T F N * adv. tail T F N * +++++++++++|+++++++++++|++++++++++|XXXXXX @@ -217,8 +219,9 @@ Segment *segments; * adv. tail back T FN * adv. nose find T F N * +++++++++++|+++++++++++|++++++++++|XXXXXX - * adv. fdet 1 seg T N F - * adv. nose T N HorizonReached + * adv. fdet stopdist T N F } may give + * adv. nose T F N } HorizonReached + * adv. tail T F N instead * */ @@ -232,8 +235,10 @@ Segment *segments; typedef struct { Train *train; unsigned + done_first_new_fdet:1, count_time:1, accelerating:1, + stopping:1, usecurrentposn:1, /* for pred_getmovpos */ optimistic:1, /* for autopoint */ alwaysusemotions:1, /* for report_train_ownerships only */ @@ -244,7 +249,7 @@ typedef struct { TrackLocation nose, fdet, tail; TrackAdvanceContext nosec, tailc, fdetc; TimeInterval elapsed; /* from now, minimum */ - Distance was_distance, autopoint_distance; + Distance was_distance, autopoint_distance, stopping_distance; double maxspeed; Segment *hindmost, *furthest; @@ -391,9 +396,7 @@ static int nose_nextseg(TrackLocation *t, TrackAdvanceContext *c, /* Is it empty ? */ - if (!u->accelerating && - speedmanager_stopping(u->train) && - t->seg->owner != u->train) + if (u->stopping && t->seg->owner != u->train) return EC_SignallingHorizonReached; if (t->seg->owner) { @@ -556,13 +559,16 @@ static int fdet_nextseg(TrackLocation *t, TrackAdvanceContext *c, return predict_problem(u, t->seg, "cannot set track polarity"); } - if (u->was_distance == TL_DIST_INF) { + if (!u->done_first_new_fdet) { t->seg->det_expected= 1; + u->done_first_new_fdet= 1; u->walk_compute_polarise= u->need_polarise= (t->seg->seg_inverted ^ t->seg->tr_backwards ^ u->train_polarity_inverted); + } + if (u->was_distance == TL_DIST_INF) { if (u->train->autopoint) { const SegPosCombInfo *pci; r= trackloc_getlink(t,c,&pci,0,-1); assert(!r); @@ -603,11 +609,8 @@ static int fdet_nextseg(TrackLocation *t, TrackAdvanceContext *c, /* Final adjustments, prepare for next iteration */ - if (u->was_distance == TL_DIST_INF) { - c->distance= speedmanager_stoppingdistance(u->train); - oprintf(DUPO("safety") " predict stoppingdistance=%d\n", - c->distance); - } + if (u->was_distance == TL_DIST_INF) + c->distance= u->stopping_distance; u->was_distance= c->distance; u->count_time= 1; /* we start counting time only after we've done the @@ -647,13 +650,17 @@ ErrorCode predict(Train *tra, int accelerate, u.problem_callback= ppc; u.problem_callback_u= ppcu; u.maxspeed= speedmanager_speed_maxestimate(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) accel=%d\n", + " (speed %f try %f, step %d%s) stopdist=%d%s%s\n", tra->backwards?"-":"",tra->pname, u.maxspeed, tra->speed.speed, tra->speed.try_speed, tra->speed.step, tra->speed.decel.running ? " decel" : "", - accelerate); + u.stopping_distance, + accelerate ? " accel" : "", + u.stopping ? " stopping" : ""); FOR_SEG { seg->det_expected= 0; @@ -711,7 +718,8 @@ ErrorCode predict(Train *tra, int accelerate, /* predict the future */ - u.fdetc.distance= u.was_distance= TL_DIST_INF; + u.fdetc.distance= u.was_distance= + u.stopping ? u.stopping_distance : TL_DIST_INF; u.fdetc.nextseg= fdet_nextseg; u.fdetc.getmovpos= pred_getmovpos; u.fdetc.trackend= pred_trackend; @@ -908,6 +916,7 @@ void safety_notify_detection(Segment *seg) { Train *tra; ErrorCode ec; Segment *interferer; + int stopdist, maxinto; if (seg->det_ignore) return; if (!seg->det_expected) { @@ -926,10 +935,12 @@ void safety_notify_detection(Segment *seg) { if (seg->movposcomb < 0) safety_panic(tra,seg, "track route not set and train has arrived"); - tra->foredetect= seg; - tra->uncertainty= tra->maxinto= - seg->i->poscombs[seg->movposcomb].dist; + stopdist= speedmanager_stoppingdistance(tra); + maxinto= seg->i->poscombs[seg->movposcomb].dist; + if (speedmanager_stopping(tra) && maxinto > stopdist) maxinto= stopdist; + tra->foredetect= seg; + tra->uncertainty= tra->maxinto= stopdist; report_train_position(tra); ec= predict(tra, 0, detection_report_problem, 0); @@ -937,7 +948,12 @@ void safety_notify_detection(Segment *seg) { assert(ec == EC_SignallingPredictedProblem); - tra->maxinto= tra->uncertainty= 1; + if (tra->maxinto > stopdist) { + tra->uncertainty= tra->maxinto= stopdist; + report_train_position(tra); + } + + report_train_position(tra); ec= speedmanager_speedchange_request(tra,0, 0,(char*)"detection sigstop"); /* that calls predict_confirm with our supplied arguments */ -- 2.30.2