chiark / gitweb /
new realtime/safety compiles
authorian <ian>
Tue, 22 Apr 2008 21:33:08 +0000 (21:33 +0000)
committerian <ian>
Tue, 22 Apr 2008 21:33:08 +0000 (21:33 +0000)
13 files changed:
hostside/Makefile
hostside/commands.c
hostside/errorcodes.h.gen
hostside/movpos.c
hostside/persist.c
hostside/record-i.h
hostside/record-y.y
hostside/record.c
hostside/resolve.c
hostside/safety.c
hostside/safety.h
hostside/speed.c
hostside/trackloc.c

index 95873fe9a245c037420674a1dce248745c8c912a..55a6ea60b4d0562378c88e3f434d6b51e78ad6f4 100644 (file)
@@ -35,7 +35,7 @@ realtime:     realtime.o startup.o cdumgr.o safety.o trackloc.o       \
                 utils.o serialio.o parseutils.o auproto-pic.o          \
                 nmra.o encode.o movpos.o                               \
                 ../layout/ours.layout-data.o                           \
-                __oop-read-copy.o -loop
+                __oop-read-copy.o -loop -lm
                $(LINK)
 
 proto-expanded:        ../cebpic/README.protocol
index f12362ea714b6f9db6410fd4cf46ead2ee86a873..c17e3524e40feab4da2cc1aabe0d3f3ebac2b189 100644 (file)
@@ -27,6 +27,19 @@ struct ManualRetransmitNode {
 #endif
 #endif
 
+
+static void cmd_ppc(Train *tra, Segment *seg, void *pu, const char *message) {
+  const CmdInfo *ci= pu;
+  oprintf(UPO,"ack SignallingPredictedProblem %s %s", ci->name, message);
+}
+
+#define MUSTECRPREDICT(requester) do{                                  \
+    int mustecr__ec= (requester);                                      \
+    if (mustecr__ec==EC_SignallingPredictedProblem) return EC_BadCmd;  \
+    if (mustecr__ec) return mustecr__ec;                               \
+  }while(0)
+#define CMDPPC cmd_ppc,(void*)ci
+
 struct NmraParseEncodeCaller {
   ParseState *ps;
   unsigned long arg[NMRA_MAX_NARGS];
@@ -206,7 +219,7 @@ static int ps_needtrain(ParseState *ps, Train **tra_r) {
 }
 
 static int cmd_movfeat(ParseState *ps, const CmdInfo *ci) {
-  Segment *move, *back, *fwd;
+  Segment *move;
   const SegmentInfo *movei;
   long ms;
   long poscomb;
@@ -214,16 +227,16 @@ static int cmd_movfeat(ParseState *ps, const CmdInfo *ci) {
   MUSTECR( ps_needsegmentperhaps(ps,&move,&movei) );
   MUSTECR( ps_needword(ps) );
   if (CTYPE(isdigit,*ps->thisword)) {
-    back= fwd= 0;
     if (!move) badcmd(ps,"invalid movement specification");
     ps_pushbackword(ps);
     MUSTECR( ps_neednumber(ps,&poscomb,0,movei->n_poscombs,
                           "position number") );
   } else {
-    poscomb= -1;
+    Segment *back, *fwd;
     back= move;
     MUSTECR( ps_needsegment(ps,&move,&movei) );
     MUSTECR( ps_needsegmentperhaps(ps,&fwd,0) );
+    MUSTECR( movpos_findcomb_bysegs(back,move,fwd,move->movposcomb,&poscomb) );
   }
   
   ms= INT_MAX;
@@ -233,44 +246,25 @@ static int cmd_movfeat(ParseState *ps, const CmdInfo *ci) {
   MUSTECR( ps_neednoargs(ps) );
 
   if (!ci->xarg)
-    MUSTECR( safety_check_movposchange(move) );
+    MUSTECRPREDICT( safety_check_movposchange(move,CMDPPC) );
   
-  MUSTECR( movpos_change_bysegs(back,move,fwd,ms,0) );
+  MUSTECR( movpos_change(move,poscomb,ms,0) );
 
   return 0;
 }
 
 static int cmd_speed(ParseState *ps, const CmdInfo *ci) {
-  long speed, max;
-  int curvesz;
+  long speed;
   Train *tra;
   
   MUSTECR( ps_needtrain(ps,&tra) );
-  curvesz= tra->accel.curvesz;
 
-  switch (ci->xarg) {
-  case 0: max=INT_MAX; break;
-  case 1: max=1000;    break;
-  case 2: max=126;     break;
-  default: abort();
-  }
-
-  MUSTECR( ps_neednumber(ps,&speed,0,max,"speed step") );
+  MUSTECR( ps_neednumber(ps,&speed,0,126,"speed step") );
   MUSTECR( ps_neednoargs(ps) );
 
-  switch (ci->xarg) {
-  case 0:
-    break;
-  case 1:
-    speed= speed / 1000.0 * tra->accel.curve[curvesz-1].speed;
-    break;
-  case 2:
-    if (speed >= curvesz) speed= curvesz-1;
-    speed= tra->accel.curve[speed].speed;
-    break;
-  }
+  MUSTECRPREDICT( speedmanager_speedchange_request(tra,speed,CMDPPC) );
 
-  return safety_requestspeed(tra, speed);
+  return 0;
 }
 
 const CmdInfo toplevel_cmds[]= {
@@ -279,8 +273,6 @@ const CmdInfo toplevel_cmds[]= {
   { "noop",       cmd_noop        },
   { "movfeat",    cmd_movfeat     },
   { "movfeat!",   cmd_movfeat, 1  },
-  { "speedmms",   cmd_speed,   1  },
-  { "speedpermil",cmd_speed,   2  },
-  { "speed126",   cmd_speed,   0  },
+  { "speed",      cmd_speed       },
   { 0 }
 };
index b4927f2acc8593fa67b43614d9f85fc7f87f9d8f..64784a0d122837cc356b6f6e36bf78eab8446925 100755 (executable)
@@ -5,9 +5,9 @@
        MovFeatTooLate
        MovFeatKindsCombination
        MovFeatReservationInapplicable
+       MovFeatRouteNotFound
        BufferFull
        BadCmd
-       NotFound
        SignallingPredictedProblem
        SignallingHorizonReached
        );
index 5d2235bd9e203fed8d5a7c263ee56d0f24b4176e..4a89d44f04a275ff9a0ba42329f4ca5330643c3a 100644 (file)
@@ -16,7 +16,7 @@ typedef struct KindInfo KindInfo;
 /* Kind-independent code is responsible for determining
  * the method, doing a bit of cleanup, and adjusting the flow
  * slightly.  Per-kind code does the actual work and is mostly in
- * charge - it is also responsible for updating seg->moving.
+ * charge - it is also responsible for updating seg->moving and ->motion.
  */
 /* The following states exist for each MovPosChange
  * at points when control flow  passes between kind and indep:
@@ -26,7 +26,7 @@ typedef struct KindInfo KindInfo;
  *   C  Confirmed    motion queued and will occur
  *   D  Done         motion is complete and callback just needs to be made
  *   E  Erroneous    indep must call destroy straight away
- * seg->moving is in one of the states UC
+ * seg->moving and ->motion is in one of the states UC
  */
 
 typedef struct MovPosChange {      /* valid in:   filled in by and when:     */
@@ -38,7 +38,7 @@ typedef struct MovPosChange {      /* valid in:   filled in by and when:     */
 } Change;
   /* `actual' contains the kind's public opinion about the physical
    * state.  It is initialised by indep (just before confirm) from
-   * move->moving->actual or move->movposcomb as the case may be.  It
+   * move->motion->actual or move->movposcomb as the case may be.  It
    * should be updated by the kind, since it is used by indep for
    * calculating the number and identities of the features which may
    * need to change when a new move request is intended to replace an
@@ -58,8 +58,8 @@ struct KindInfo {
   /* indep guarantees that
    *   alloc_motions >= move->i->n_motions    on reserve
    *   alloc_motions >= n_motions             on confirm
-   * and that if on entry to reserve move->moving is non-0,
-   *  it is of the same kind
+   * and that if on entry to reserve move->motion is non-0,
+   *  it move->motion is non-0 and of the same kind
    */
 };
 
@@ -326,8 +326,9 @@ fprintf(stderr,"  point confirm\n");
   /* state A or R */
   pt_dequeue(r);
                                            /* states of existing: */
-  PointReq *existing= (PointReq*)move->moving;     /* U or C */
-  if (existing) pt_dequeue(existing);              /* U or CA */
+  PointReq *existing=
+    move->moving ? (PointReq*)move->motion : 0;   /* U or C */
+  if (existing) pt_dequeue(existing);             /* U or CA */
 
   /* state A or RA */
   memcpy(r->motions, motions, sizeof(r->motions[0])*n_motions);
@@ -362,7 +363,8 @@ fprintf(stderr,"  point confirm\n");
    */
 
   if (!ec) {
-    move->moving= chg;
+    move->moving= 1;
+    move->motion= chg;
     move->movposcomb= -1;
     pt_check_action();
   }
@@ -410,11 +412,12 @@ static void pt_check_action(void) {
      * eg if we are asked to move the 
      */
     Segment *move= r->h.move;
-    assert(move->moving == (Change*)r);
+    assert(move->moving && move->motion == (Change*)r);
     pt_queue_remove_index(&pt_confirmed,0);
     pt_mark_as_allocated(r); /* now state A aka Done */
     move->movposcomb= r->h.actual;
     move->moving= 0;
+    move->motion= 0;
     free(r);
     pt_check_action();
   }
@@ -430,8 +433,9 @@ void points_all_abandon(void) {
   for (i=0; i<pt_confirmed.n; i++) {
     PointReq *r= pt_confirmed.l[i];
     Segment *move= r->h.move;
-    assert(move->moving == (Change*)r);
+    assert(move->motion == (Change*)r);
     move->moving= 0;
+    move->motion= 0;
     move->movposcomb= r->h.actual;
     free(r);
   }
@@ -506,7 +510,7 @@ static int evaluate_target(Segment *move, MovPosComb target,
 
   if (startpoint<0) startpoint= movpos_poscomb_actual(move);
 
-  for (feat=0, feati=movei->movfeats, tchanges=0, kind= mfk_none;;
+  for (feat=0, feati=movei->movfeats, tchanges=0, kind= mfk_none;
        feat<movei->n_movfeats;
        feat++, feati++) {
     if (!change_needed(feati,target,startpoint)) continue;
@@ -529,8 +533,8 @@ ErrorCode movpos_findcomb_bysegs(Segment *back, Segment *move, Segment *fwd,
   for (tcomb=0, pci=movei->poscombs;
        tcomb<movei->n_poscombs;
        tcomb++, pci++) {
-    Segment *tback= &segments[pci->backwards.next];
-    Segment *tfwd=  &segments[pci->forwards .next];
+    Segment *tback= &segments[pci->link[1].next];
+    Segment *tfwd=  &segments[pci->link[0].next];
     if (back && !(back==tback || back==tfwd)) continue;
     if (fwd  && !(fwd ==tback || fwd ==tfwd)) continue;
 
@@ -552,8 +556,8 @@ ErrorCode movpos_findcomb_bysegs(Segment *back, Segment *move, Segment *fwd,
   }
   if (*chosen_r) *chosen_r= bestcomb;
   return
-    tchanges==INT_MAX ? EC_Invalid :
-    tchanges==INT_MAX-1 ? EC_MovFeatKindsCombination :
+    bestchanges==INT_MAX ? EC_MovFeatRouteNotFound :
+    bestchanges==INT_MAX-1 ? EC_MovFeatKindsCombination :
     0;
 }
 
@@ -603,7 +607,7 @@ fprintf(stderr,"    motion %s %lu kind=%d\n",feati->pname,posn,kind);
     if (chg) {
       if (chg->ki != ki ||
          chg->move != move ||
-         chg->intent != intent)
+         chg->intent != target)
        return EC_MovFeatReservationInapplicable;
     } else {
       chg= mp_allocate(ki,move,n_motions,target);
@@ -626,12 +630,11 @@ ErrorCode
 movpos_reserve(Segment *move, int maxdelay_ms, MovPosChange **res_r,
               MovPosComb target, MovPosComb startpoint /*as for findcomb*/) {
   MovFeatKind kind= mfk_none;
-  const MovFeatInfo *feati;
   ErrorCode ec;
-  int feat, nchanges;
+  int nchanges;
 
   nchanges= evaluate_target(move,target,startpoint,&kind);
-  if (nchanges=-1) return EC_MovFeatKindsCombination;
+  if (nchanges==-1) return EC_MovFeatKindsCombination;
 
   const KindInfo *ki= &methodinfos[kind];
   Change *chg= mp_allocate(ki, move, move->i->n_movfeats, target);
@@ -652,7 +655,7 @@ void movpos_unreserve(MovPosChange *res) {
 }
 
 MovPosComb movpos_poscomb_actual(Segment *seg) {
- return seg->moving ? seg->moving->actual : seg->movposcomb;
+ return seg->moving ? seg->motion->actual : seg->movposcomb;
 }
 
 MovPosComb movpos_change_intent(MovPosChange *chg) {
index 01171e520f9bf36211c2f61dd117a97bc5b3927f..d10a3ea45a9dae063d29d83330aefe9ad9b4ec14 100644 (file)
@@ -362,29 +362,21 @@ static void persist_mapread(void) {
   mapmem(0, datalen, PROT_READ);
 }
 
+#define SANE_SEGMENT(seg)
+
 void persist_entrails_run_converter(void) {
-  TRA_IV;
   SEG_IV;
   MovPosComb report;
 
   persist_mapread();
 
-  FOR_TRA {
-    if (!tra->pname || !tra->foredetect ||
-       !tra->foredetect->i || !tra->foredetect->i->pname)
-      continue;
-    printf("train %s at %s%s:%d-+%d\n",
-          tra->pname, tra->backwards ? "-" : "",
-fixme tra->backwards is wrong
- need to provide both tra->backwards and tr_backwards
-          tra->foredetect->i->pname, tra->mininto, tra->uncertainty);
-  }
   FOR_SEG {
     if (seg->i != segi || !segi->pname ||
        !seg->owner || !seg->owner->pname)
       continue;
-    printf("seg %s has %s%s\n",
-          segi->pname, seg->tr_backwards ? "-" : "", seg->owner->pname);
+    printf("seg %s has %s%s\n", segi->pname,
+          (seg->tr_backwards & seg->owner->backwards) ? "-" : "",
+          seg->owner->pname);
 
     if (segi->n_poscombs>1 &&
        (report= movpos_poscomb_actual(seg)) >=0 &&
index ff0ba8753e286c77bba8096171ce62b62c5aa73b..e876cf7c2c7e671d9a78b239a7c021cc7599a7cd 100644 (file)
@@ -7,12 +7,11 @@
 #include "record.h"
 #include "record-y.h"
 
-void record_train_at(Train *tra, int backw, Segment *seg);
 void record_train_is(Train *tra, int addr, int head, int det, int tail);
+void record_train_home(Train *tra, int backw, Segment *seg);
 void record_train_step_speed(Train *tra, int step, double speed);
 void record_train_stopregime_count(void);
 void record_train_stopregime(Train *tra, double speed, int xs, int ts);
-void record_train_home(Train *tra, int backw, Segment *seg);
 void record_seg_has(Segment *seg, int backw, Train *tra);
 void record_seg_at(Segment *seg, const char *movposcomb_pname);
 void record_feature_nmrafeat(FeaturesFeature*, FeaturesAddr*, int num);
index 984fa9cdad85c82945dc0843f7103aa4991c8b2e..964b0cb9531d9d54f754e94f252578fe38587a53 100644 (file)
@@ -44,12 +44,6 @@ line:                /* empty */
        |       TRAIN train IS NUM NUM '+' NUM '+' NUM
        {         if ($2) record_train_is($2,$4,$5,$7,$9);
        }
-       |       TRAIN train AT backwards seg ':' NUM '+' '-' NUM
-       {         if ($2) record_train_at($2,$4,$5,$7,$10);
-       }
-       |       TRAIN train AT backwards seg ':' NUM '+' '-' NUM
-       {         if ($2) record_train_at($2,$4,$5,$7,$10);
-       }
        |       TRAIN train HOME { cur_train=$2; } segments
        {
        }
index b75964bbc9298df2041780fbc1a9e1ea71c0ff64..3dcfe58aecaae334c7a94de10bb2c997d504930c 100644 (file)
@@ -184,13 +184,6 @@ void record_train_is(Train *tra, int addr, int head, int det, int tail) {
   tra->tail= tail;
 }
 
-void record_train_at(Train *tra, int backw, Segment *seg, int mini, int unc) {
-  tra->foredetect= seg;
-  tra->maxinto= maxi;
-  tra->uncertainty= unc;
-  tra->backwards= backw;
-}
-  
 void record_train_home(Train *tra, int backw, Segment *seg) {
   if (!tra) return;
   seg->home= tra;
@@ -268,7 +261,7 @@ void record_train_stopregime_count(void) {
 
 void record_train_stopregime(Train *tra, double from, int xs, int ts) {
   Train *other;
-  SpeedRangeEntry *new;
+  SpeedRange *new;
   int i;
 
   if (rangebufused >= rangebufsz)
@@ -310,13 +303,14 @@ void record_train_stopregime(Train *tra, double from, int xs, int ts) {
 
 static int speedregime_compare(const void *av, const void *bv) {
   const SpeedRange *a= av, *b= bv;
-  if (a->step == b->step)
-    record_yyerror("multiple speed curve points at same step");
-  return a->step - b->step;
+  if (a->speed == b->speed)
+    record_yyerror("multiple identical speed regimes");
+  return a->speed > b->speed ? 1 : -1;
 }
 
 static void speeds_postprocess(void) {
   TRA_IV;
+  int step;
 
   FOR_TRA {
     if (!tra->speedregimes || tra->speedcurve[1]<0) {
@@ -365,7 +359,7 @@ static void alloc(void) {
   SEG_IV;
   void *mapbase=0;
   char **trap;
-  int phase, offset, datalen=0;
+  int phase, offset, datalen=0, step;
 
 #define ALLOC(array,count) \
   ((array)= alloc_some(mapbase,&offset,sizeof(*(array)),(count)))
@@ -423,7 +417,7 @@ static void alloc(void) {
       datalen= offset;
   }
 
-  curvebuf= mmalloc(sizeof(*curvebuf) * curvebufsz);
+  rangebuf= mmalloc(sizeof(*rangebuf) * rangebufsz);
 }
   
 /*---------- entrypoint from main, and its subroutines ----------*/
@@ -449,7 +443,7 @@ static void parse_pass(const char **argv) {
 }
 
 void records_parse(const char **argv) {
-  parse_pass(argv); /* trains==0: counts trains and curve points. */
+  parse_pass(argv); /* trains==0: counts trains and speed ranges. */
   alloc();
   parse_pass(argv); /* trains!=0: populates data area */
   record_tempzone_clear();
index 11dad34911724ffc5d6daa982b49f58c0c15e37a..35a6539e0ce9bf202f530f2abe2f3d681380b122 100644 (file)
@@ -320,9 +320,6 @@ int resolve_complete(void) {
       target= d->movposcomb;
     }      
 
-    if (d->owner)
-      d->until_here= 1e-3;
-
     if (d->i->n_poscombs>1) {
       d->movposcomb= -1;
       if (target >= 0) {
@@ -340,12 +337,6 @@ int resolve_complete(void) {
     }
   }
 
-  FOR_TRAIN(t,NOOP,NOOP) {
-    t->speed= 0;
-    if (t->resolution == RR_E)
-      t->backwards= 0;
-  }
-
   if (problems) {
   x_problems:
     oprintf(UPO,"resolution problems %d\n",problems);
@@ -371,10 +362,10 @@ static int segdist(Segment *seg) {
 static int findhead_nextseg(TrackLocation *t, struct TrackAdvanceContext *c,
                            MovPosComb *mpc_io, Segment *before) {
   FindEndUserContext *u= c->u;
-  if (t->seg->owner != train) return -1;
+  if (t->seg->owner != u->train) return -1;
   if (!t->seg->res_detect) { u->extraspace= 0; return -1; }
   
-  u->train->foredetect= seg;
+  u->train->foredetect= t->seg;
   t->seg->tr_backwards= t->backwards;
   t->seg->res_detect= 0;
   return 0;
@@ -382,16 +373,20 @@ static int findhead_nextseg(TrackLocation *t, struct TrackAdvanceContext *c,
 
 static int walkback_nextseg(TrackLocation *t, struct TrackAdvanceContext *c,
                            MovPosComb *mpc_io, Segment *before) {
-  if (t->seg->owner != train) return -1;
+  FindEndUserContext *u= c->u;
+  if (t->seg->owner != u->train) return -1;
   t->seg->tr_backwards= !t->backwards;
   t->seg->resfin_done= 1;
+  return 0;
 }
 
 static void resolve_train_finalise(Segment *startpoint) {
+  SEG_IV;
   Train *tra;
   TrackLocation t;
   TrackAdvanceContext tc;
   FindEndUserContext u;
+  int r;
 
   assert(startpoint->owner);
   tra= startpoint->owner;
@@ -410,11 +405,10 @@ static void resolve_train_finalise(Segment *startpoint) {
 
   u.extraspace= MARGIN_NOSE + tra->head;
 
-  r= findhead_nextseg(&t,&c,0,0); assert(!r);
+  r= findhead_nextseg(&t,&tc,0,0); assert(!r);
   trackloc_advance(&t,&tc);
 
-  tra->foredetect= u->foredetect;
-  tra->maxinto= segdist(tra->foredetect) - u->extraspace;
+  tra->maxinto= segdist(tra->foredetect) - u.extraspace;
   if (tra->maxinto < 0) tra->maxinto= 0;
   tra->uncertainty= tra->maxinto;
 
@@ -433,8 +427,8 @@ static void resolve_train_finalise(Segment *startpoint) {
   r= walkback_nextseg(&t,&tc,0,0); assert(!r);
   trackloc_advance(&t,&tc);
 
-  if (u->distance) {
-    tra->uncertainty -= u->distance;
+  if (tc.distance) {
+    tra->uncertainty -= tc.distance;
     if (tra->uncertainty < 0)
       safety_panic(tra, t.seg, "resolved train location too small by %d!",
                   -tra->uncertainty);
index 1eaf1e20d47c5dc901bb71645749a54707d97d5e..0501bef1663b5c367dd7dc8cab32f750f70bce05 100644 (file)
@@ -252,6 +252,10 @@ typedef struct {
   int noninv_tally[2];
 } PredictUserContext;
 
+static int nose_length(Train *tra) {
+  return MARGIN_NOSE + (tra->backwards ? tra->tail : tra->head);
+}
+
 /*---------- prediction problem reporting ----------*/
 
 static ErrorCode predict_vproblem(PredictUserContext *u, Segment *seg,
@@ -323,7 +327,7 @@ static int nose_nextseg(TrackLocation *t, TrackAdvanceContext *c,
 
   /* Is it empty ? */
 
-  if (speedmanager_stopping(train) && t->seg->owner != u->train)
+  if (speedmanager_stopping(u->train) && t->seg->owner != u->train)
     return EC_SignallingHorizonReached;
 
   if (t->seg->owner) {
@@ -442,7 +446,7 @@ static int fdet_nextseg(TrackLocation *t, TrackAdvanceContext *c,
 
   u->nosec.distance= advanced;
   r= trackloc_advance(&u->nose,&u->nosec);
-  if (r == SignallingHorizonReached &&
+  if (r == EC_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
@@ -451,7 +455,7 @@ static int fdet_nextseg(TrackLocation *t, TrackAdvanceContext *c,
     int adjust= nose_length(u->train);
     if (adjust > u->train->maxinto) adjust= u->train->maxinto;
     u->train->maxinto -= adjust;
-    u->train->uncertainto += adjust;
+    u->train->uncertainty += adjust;
   }
   if (r) return r;
 
@@ -523,10 +527,6 @@ 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;
@@ -653,16 +653,16 @@ static void detection_report_problem(Train *tra, Segment *seg,
 
 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");
+
+  tra= seg->owner;
   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=
     seg->i->poscombs[seg->movposcomb].dist;
@@ -677,12 +677,16 @@ void safety_notify_detection(Segment *seg) {
   assert(!ec);
 }
 
-ErrorCode safety_check_movposchange(Segment *seg) {
+ErrorCode safety_check_movposchange(Segment *seg,
+                           PredictionProblemCallback *ppc, void *ppcu) {
+  PredictUserContext u;
+
+  u.problem_callback= ppc;
+  u.problem_callback_u= ppcu;
+  u.train= seg->owner;
+
   if (seg->owner) {
-    oprintf(UPO,"ack SignallingProblemPredicted @%s %s:"
-           " route set for approaching train",
-           seg->i->pname, seg->owner->pname);
-    return EC_BadCmd;
+    return predict_problem(&u,seg, " route set for approaching train");
   }
   return 0;
 }
index 67b3704ace9fca94fd45bf0f25661416b5d4b93e..4a1ff6cbbdfe202ba979a97238cb47b175a20aad 100644 (file)
@@ -108,7 +108,8 @@ void safety_setdirection(Train* tra, int backwards);
 void safety_notify_detection(Segment *seg);
   /* Called by startup.c when new train detection occurs in state Run. */
 
-ErrorCode safety_check_movposchange(Segment *seg);
+ErrorCode safety_check_movposchange(Segment *seg,
+                           PredictionProblemCallback *ppc, void *ppcu);
   /* If this check success, caller may call movpos_change */
 
 ErrorCode predict_confirm(Train *tra, int accelerate,
@@ -206,7 +207,7 @@ ErrorCode speedmanager_speedchange_request(Train *tra, int step,
 void speedmanager_reset_train(Train *tra);
 double speedmanager_speed_maxestimate(Train *tra);
 double speedmanager_stoppingdistance(Train *tra);
-int speedmanager_speed_stopping(Train *tra);
+int speedmanager_stopping(Train *tra);
 
 /*========== actual.c ==========*/
 /* actual.c should only be called from safety.c.
@@ -297,6 +298,8 @@ int trackloc_advance(TrackLocation *t, TrackAdvanceContext *c);
    * traversed. */
 
 int trackloc_reverse_exact(TrackLocation *t, TrackAdvanceContext *c);
+int trackloc_set_exactinto(TrackLocation *t, TrackAdvanceContext *c,
+                          Segment *seg, int backwards, int into);
   /* c is used just as for trackloc_getlink.
    * If we can't determine the movposcombs we call abort. */
 
index 6b22f254c19e5d748309427a0c41d954fce7726f..e0e932b03b1904c40e2bf0279d012243a52c8d21 100644 (file)
@@ -79,7 +79,7 @@ double speedmanager_stoppingdistance(Train *tra) {
   return xs;
 }
 
-int speedmanager_speed_stopping(Train *tra) {
+int speedmanager_stopping(Train *tra) {
   return tra->speed.try_speed < 0 && !tra->speed.speed;
 }  
 
index 5dfdffa31276ceb0d62009f8e9a6b7328b962ae3..98a6e3762212e1feafded9328ddd5cac6478f97e 100644 (file)
@@ -13,6 +13,21 @@ void trackloc_set_maxinto(TrackLocation *tloc, Segment *seg, int backwards) {
   tloc->remain= 0;
 }
 
+int trackloc_set_exactinto(TrackLocation *t, TrackAdvanceContext *c,
+                          Segment *seg, int backwards, int into) {
+  const SegPosCombInfo *pci;
+  int r;
+
+  r= trackloc_getlink(t,c,&pci,0,-1);
+  if (r) return r;
+  assert(pci);
+  
+  t->seg= seg;
+  t->backwards= backwards;
+  t->remain= pci->dist - into;
+  return 0;
+}
+
 /*---------- enquirers ----------*/
 
 int trackloc_getlink(TrackLocation *t, TrackAdvanceContext *c,
@@ -49,7 +64,6 @@ int trackloc_advance(TrackLocation *t, TrackAdvanceContext *c) {
   const SegPosCombInfo *pci;
   const SegmentLinkInfo *link;
   MovPosComb mpc_nego;
-  int leaving_back;
   int r;
 
   r= trackloc_getlink(t,c, 0,&link, t->seg->movposcomb);