chiark / gitweb /
when train is stopping, do not advance to next segment detection first, and remain...
authorian <ian>
Mon, 5 May 2008 12:58:42 +0000 (12:58 +0000)
committerian <ian>
Mon, 5 May 2008 12:58:42 +0000 (12:58 +0000)
hostside/TODO
hostside/safety.c

index 4859f14cf71900dd35568dd943434039feb98af4..e9b189bab9c676a359c42f1e5a4af34cc25c4ce4 100644 (file)
@@ -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.
 
index 803512eaad448bc047c7b484a1e145ad046965d2..851ed8a73216dbd11797f59aadf947d2459e9383 100644 (file)
@@ -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 */