chiark / gitweb /
before much simpler resolve train placement
authorian <ian>
Tue, 22 Apr 2008 20:15:14 +0000 (20:15 +0000)
committerian <ian>
Tue, 22 Apr 2008 20:15:14 +0000 (20:15 +0000)
hostside/resolve.c
hostside/safety.c
hostside/safety.h
hostside/speed.c
hostside/trackloc.c

index c4629473f09ac2d3b0bb2e165a9a654771f322db..c43e26908ef5d9484c583ecf162c59cdfb149698 100644 (file)
@@ -357,26 +357,95 @@ int resolve_complete(void) {
   return 0;
 }
 
-static int rtf_nextseg(TrackLocation *t, struct TrackAdvanceContext *c,
-                      MovPosComb *mpc_io, Segment *before) {
-  if (t->seg->owner != before->owner)
-    return -1;
-  t->seg->owner->foredetect= t->seg;
+typedef struct {
+  Train *train;
+  Segment *foredetect;
+  int minclear, backwards;
+} FindEndUserContext;
+
+static int segdist(Segment *seg) {
+  assert(seg->movposcomb >= 0);
+  return seg->i->poscombs[seg->movposcomb].dist;
+}
+
+static int foundend(FindEndUserContext *u, Segment *seg) {
+  u->foredetect= seg;
+  return -1;
+}
+static int findend_nextseg(TrackLocation *t, struct TrackAdvanceContext *c,
+                          MovPosComb *mpc_io, Segment *before) {
+  FindEndUserContext *u= c->u;
+  t->seg->tr_backwards= t->backwards ^ u->backwards;
+  if (t->seg->owner != train) return foundend(u, before);
+  if (!t->seg->res_detect) { u->minclear= 0; return foundend(u, before);
+  return 0;
+}
+static int findend_trackend(TrackLocation *t, struct TrackAdvanceContext *c) {
+  FindEndUserContext *u= c->u;
+  return foundend(u, t->seg);
 }
 
-static void resolve_train_finalise(Train *tra) {
+static void resolve_train_finalise(Segment *startpoint) {
+  Train *tra;
   TrackLocation t;
   TrackAdvanceContext tc;
+  FindEndUserContext u;
 
-  t.seg= tra->foredetect;
+  assert(startpoint->owner);
+  tra= startpoint->owner;
+
+  startpoint->res_detect= 0; /* clear these as we use them up */
+
+  t.seg= startpoint;
   t.remain= 0;
-  t.backwards= t.seg->tr_backwards;
+  t.backwards= t.seg->tr_backwards ^ tra->backwards;
+    /* we're going to clear tra->backwards */
+
   tc.distance= INT_MAX;
-  tc.nextseg= rtf_nextseg;
+  tc.nextseg= findend_nextseg;
+  tc.trackend= findend_trackend;
   tc.getmovpos= 0;
-  tc.trackend= 0;
+  tc.u= &u;
+
+  u.minclear= MARGIN_NOSE + tra->head;
+  u.backwards= 0;
+
+  r= trackloc_advance(&t,&tc);  assert(!r);
+
+  tra->foredetect= u->foredetect;
+  tra->maxinto= segdist(tra->foredetect) - u->minclear;
+  if (tra->maxinto < 0) tra->maxinto= 0;
+  tra->uncertainty= tra->maxinto;
+
+  t.seg= tra->foredetect;
+  t.remain= 
+
+    u->maxinto= u->uncertainty= segdist(before);
+
+      
+    u->detcanoccupy= tra->head;
+    return -1;
+
+t->seg->res_detect
+  if (
+  
+
+  if (t->seg->owner != before->owner)
+    return -1;
+  t->seg->owner->foredetect= t->seg;
+}
+
+
+
+  
+
+  tra->backwards= 0;
+  
+  t.seg= tra->foredetect;
+  t.remain= 0;
 
   trackloc_advance(&t,&tc);
+    }
 
   
 
@@ -412,14 +481,15 @@ void resolve_motioncheck(void) {
     if (seg->moving) return;
 
   FOR_SEG
-    if (seg->res_detect) {
-      assert(seg->owner);
+    if (seg->res_detect)
+      resolve_train_finalise(seg);
+
+    
       seg->owner->foredetect= seg; /* initial guess */
     }
   
 
   FOR_TRA
-    resolve_train_finalise(tra);
 
   FOR_SEG {
     if (seg->res_detect) {
index 1d00aeab6458ea0ea2d6935740caf5f4042eea92..5bca8e3f7547b3bec05fdfa794b0c9d8bc2e7e26 100644 (file)
@@ -177,7 +177,50 @@ Segment *segments;
  *   committed to in an earlier prediction but which we have not yet
  *   reached in this prediction.
  *
- * (These are the values when not in the middle of nose_nextseg.)  */
+ * (These are the values when not in the middle of nose_nextseg.)
+ */
+/*
+ * Simulation:
+ *
+ *                                       DETECT
+ *  real stop dist                       >>>>>
+ *  simul. stop dist                                 >>>>>
+ *                   +++++++++++|+++++++++++|++++++++++|XXXXXX
+ *  set_exactinto                FNT
+ *  adv. tail back        T              FN
+ *  adv. nose find        T              F N
+ *                   +++++++++++|+++++++++++|++++++++++|XXXXXX
+ *  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. nose                               T            F N
+ *   adv. tail                                    T       F N
+ *                   +++++++++++|+++++++++++|++++++++++|XXXXXX
+ *
+ * At next detection:
+ *                                                   DETECT
+ *  real stop dist                                   >>>>>
+ *                   +++++++++++|+++++++++++|++++++++++|XXXXXX
+ *  set_exactinto                                    FNT
+ *  adv. tail back                   T       FN
+ *  adv. nose find                   T       F N
+ *                   +++++++++++|+++++++++++|++++++++++|XXXXXX
+ *  adv. fdet 1 seg                          T         N        F     
+ *   adv. nose                       T                  N     ProblemPredicted
+ *
+ * Oops, so set sigstopping and speed 0:
+ *                                                   DETECT
+ *  real stop dist                                   >>>>>
+ *                   +++++++++++|+++++++++++|++++++++++|XXXXXX
+ *  set_exactinto                                    FNT
+ *   adv. tail back                          T       FN
+ *   adv. nose find                          T       F N
+ *                   +++++++++++|+++++++++++|++++++++++|XXXXXX
+ *  adv. fdet 1 seg                          T         N        F     
+ *   adv. nose                       T                  N     HorizonReached
+ *
+ */
 
 /*========== prediction machinery ==========*/
 
@@ -244,7 +287,7 @@ static int pred_getmovpos(TrackLocation *t, TrackAdvanceContext *c,
   PredictUserContext *u= c->u;
   if (t->seg->motion) *use_io= movpos_change_intent(t->seg->motion);
   if (*use_io<0) safety_panic(u->train, t->seg,
-                             "track route unexpectedly not known");
+                             "track route unexpectedly not known");
   return 0;
 }
 
@@ -399,16 +442,20 @@ static int fdet_nextseg(TrackLocation *t, TrackAdvanceContext *c,
 
   u->nosec.distance= advanced;
   r= trackloc_advance(&u->nose,&u->nosec);
-
-  if (r==EC_SignallingHorizonReached) {
-    /* stop our prediction now */
-    advanced= u->was_distance= t->remain= 0;
-    r= 0;
+  if (r == SignallingHorizonReached &&
+      u->was_distance==INT_MAX) {
+    /* Our very first `next segment' lookahead found the end.  So we
+     * know that our nose hasn't left this segment because that's what
+     * the stopping distance is supposed to prove. */
+    assert(before == u->train->foredetect);
+    int adjust= nose_length(u->train);
+    if (adjust > u->train->maxinto) adjust= u->train->maxinto;
+    u->train->maxinto -= adjust;
+    u->train->uncertainto += adjust;
   }
-
   if (r) return r;
 
-  /* Now we have advanced the nose and have recoreded any appropriate
+  /* Now we have advanced the nose and have recorded any appropriate
    * motion(s).  But we advancing the nose has updated the segment's
    * notion of the motion but not trackloc_advance's cached version of
    * the movposcomb in *mpc_io.  That doesn't matter because we don't
@@ -446,7 +493,7 @@ static int fdet_nextseg(TrackLocation *t, TrackAdvanceContext *c,
        u->know_best_polarity= 1;
       }
     }
-    if (u->know_best_polarity && 
+    if (u->know_best_polarity &&
        !t->seg->i->invertible &&
        u->noninv_tally[ t->backwards ^ u->train_polarity_inverted ]) {
       /* incompatible, stop now */
@@ -476,6 +523,10 @@ static int fdet_nextseg(TrackLocation *t, TrackAdvanceContext *c,
 
 /*---------- prediction entrypoint ----------*/
 
+static int nose_length(Train *tra) {
+  return MARGIN_NOSE + (tra->backwards ? tra->tail : tra->head);
+}
+
 ErrorCode predict_confirm(Train *tra, int accelerate,
                          PredictionProblemCallback *ppc, void *ppcu) {
   PredictUserContext u;
@@ -489,7 +540,7 @@ ErrorCode predict_confirm(Train *tra, int accelerate,
   }
 
   foredet= tra->foredetect;
-  
+
   memset(&u,0,sizeof(u));
   u.train= tra;
   u.accelerating= accelerate;
@@ -521,7 +572,7 @@ ErrorCode predict_confirm(Train *tra, int accelerate,
   /* find the train's nose */
 
   u.nose= u.fdet;
-  u.nosec.distance= MARGIN_NOSE + (tra->backwards ? tra->tail : tra->head);
+  u.nosec.distance= nose_length(tra);
   u.nosec.nextseg= nose_nextseg;
   u.nosec.getmovpos= pred_getmovpos;
   u.nosec.trackend= pred_trackend;
@@ -542,13 +593,13 @@ ErrorCode predict_confirm(Train *tra, int accelerate,
   u.tailc.nextseg= tail_nextseg;
 
   ec= trackloc_advance(&u.fdet,&u.fdetc);
-  if (ec) goto xproblem;
+  if (ec && ec != EC_SignallingHorizonReached) goto xproblem;
 
   /*----- commit to the plan -----*/
 
   if (u.need_polarise)
     actual_inversions_start();
-  
+
   FOR_SEG {
     if (seg->owner == tra) {
       seg->det_ignore= seg->det_expected= 0;
@@ -604,13 +655,13 @@ void safety_notify_detection(Segment *seg) {
   Train *tra;
   TrackLoc tloc;
   ErrorCode ec;
-  
+
   if (seg->det_ignore) return;
   if (!seg->det_expected)
     safety_panic(0,seg, "unexpected detection");
   if (seg->movposcomb < 0)
     safety_panic(tra,seg, "track route not set and train has arrived");
-  
+
   tra= seg->owner;
   tra->foredetect= seg;
   tra->uncertainty= tra->maxinto=
@@ -618,7 +669,7 @@ void safety_notify_detection(Segment *seg) {
 
   ec= predict_confirm(tra, 0, detection_report_problem, 0);
   if (!ec) return;
-  
+
   assert(ec == EC_SignallingPredictedProblem);
 
   tra->sigstopping= 1;
index e80a073e475e17b5cedfba6e8dddac70a0578695..249337362e3897062130f5a21f384e7f878c46ad 100644 (file)
@@ -269,7 +269,8 @@ typedef struct TrackAdvanceContext {
      * May modify *use_io if it wishes.  It is OK to leave it as
      * -1 in which case advance will return whatever getmovpos did
      * (even if 0).  When called by interfering_segment, non-0 returns
-     * will be treated as an indication that the movposcomb is unknown. */
+     * will be treated as an indication that the movposcomb is unknown.
+     * On entry t->remain is invalid; it should not be modified. */
   int (*trackend)(TrackLocation *t, struct TrackAdvanceContext *c);
     /* trackloc_advance stops even if this returns 0. */
   void *u;
@@ -289,8 +290,13 @@ Segment *segment_interferes(TrackAdvanceContext *c, Segment *base);
 
 int trackloc_advance(TrackLocation *t, TrackAdvanceContext *c);
   /* Advances t by dist until distance becomes 0, some callback
-   * returns non-0, or sometimes 0 if we cannot continue and
-   * the relevant callback is missing or returned 0. */
+   * returns non-0, or sometimes 0 if we cannot continue and the
+   * relevant callback is missing or returned 0.  If we exhausted
+   * c->distance or reached the end of the track then *t is accurate;
+   * otherwise t is the segment which was problematic (passed to
+   * nextseg and perhaps getmovpos) and t->remain is set to -1.  In
+   * any case c->distance is updated by the distance successfully
+   * traversed. */
 
 int trackloc_reverse_exact(TrackLocation *t, TrackAdvanceContext *c);
   /* c is used just as for trackloc_getlink.
index fcdaecf68a1e2d8aef282f678a4c8f4e6a4a3486..2a4e013c3cda6535bfaccc7d003e75655168b569 100644 (file)
@@ -17,7 +17,8 @@ static void decel_done(TimeoutEvent *toev) {
   tra->speed.speed= tra->speedcurve[tra->speed.step];
   if (tra->sigstopping) {
     assert(!tra->speed.step);
-    resolve_train_
+    train_nose_restricttoowner(tra);
+    tra->sigstopping= 0;
 }
 
 static const SpeedRange *stop_info(Train *tra, double speed) {
index 96c589db4eeb160149d410ad439e709981ed7e06..5dfdffa31276ceb0d62009f8e9a6b7328b962ae3 100644 (file)
@@ -72,9 +72,9 @@ int trackloc_advance(TrackLocation *t, TrackAdvanceContext *c) {
       next= &segments[nextnum];
 
       leaving= t->seg;
-      leaving_back= t->backwards;
       t->seg= next;
       t->backwards ^= link->next_backwards;
+      t->remain= -1;
       mpc_nego= next->movposcomb;
 
       if (c->nextseg) {
@@ -83,11 +83,7 @@ int trackloc_advance(TrackLocation *t, TrackAdvanceContext *c) {
       }
 
       r= trackloc_getlink(t,c, &pci,&link, mpc_nego);
-      if (r || !link) {
-       t->seg=leaving;
-       t->backwards= leaving_back;
-       return r;
-      }
+      if (r || !link) return r;
 
       t->remain= pci->dist;
     }