chiark / gitweb /
wip new safety - making it compile
authorian <ian>
Mon, 21 Apr 2008 00:08:40 +0000 (00:08 +0000)
committerian <ian>
Mon, 21 Apr 2008 00:08:40 +0000 (00:08 +0000)
hostside/commands.c
hostside/errorcodes.h.gen
hostside/persist.c
hostside/realtime.h
hostside/record-i.h
hostside/record-y.y
hostside/resolve.c
hostside/safety.c
hostside/safety.h
hostside/speed.c
hostside/trackloc.c

index 0f7987c5f09f9f6b53cbd1a23831f3efd9bb3db1..f12362ea714b6f9db6410fd4cf46ead2ee86a873 100644 (file)
@@ -233,7 +233,7 @@ static int cmd_movfeat(ParseState *ps, const CmdInfo *ci) {
   MUSTECR( ps_neednoargs(ps) );
 
   if (!ci->xarg)
-    MUSTECR( safety_checkmovposchange(move) );
+    MUSTECR( safety_check_movposchange(move) );
   
   MUSTECR( movpos_change_bysegs(back,move,fwd,ms,0) );
 
index 5ccde34df6cda8c340094dd7d31714533c40ab39..b4927f2acc8593fa67b43614d9f85fc7f87f9d8f 100755 (executable)
@@ -8,7 +8,7 @@
        BufferFull
        BadCmd
        NotFound
-       SignallingProblemPredicted
+       SignallingPredictedProblem
        SignallingHorizonReached
        );
 
@@ -26,6 +26,9 @@ END
 } ErrorCode;
 
 extern $decl;
+
+#define ec2str(ec) (errorcodelist[(ec)])
+
 #define DEFINE_ERRORCODELIST_DATA \\
 $decl= { \\
 END
index 1335bc7027eef4d9d06afd54ba2cde0e25723050..4221eacfae8fb002bef084f8cf4b13b6ad219562 100644 (file)
@@ -373,9 +373,9 @@ void persist_entrails_run_converter(void) {
     if (!tra->pname || !tra->foredetect ||
        !tra->foredetect->i || !tra->foredetect->i->pname)
       continue;
-    printf("train %s at %s%s:%d+-%d\n",
+    printf("train %s at %s%s\n",
           tra->pname, tra->backwards ? "-" : "",
-          tra->foredetect->i->pname, tra->maxinto, tra->uncertainty);
+          tra->foredetect->i->pname);
   }
   FOR_SEG {
     if (seg->i != segi || !segi->pname ||
index 04dafe4eec3cfe6c69cd992b0261f5cba0c7f72c..c85b96c79bae45ae50c52b61ed2524a16241cada 100644 (file)
@@ -17,6 +17,7 @@
 #include <limits.h>
 #include <stddef.h>
 #include <ctype.h>
+#include <math.h>
 
 #include <sys/types.h>
 #include <sys/time.h>
index 3ef2a42d692865870e80317947b21af8e058044c..ff0ba8753e286c77bba8096171ce62b62c5aa73b 100644 (file)
@@ -7,10 +7,11 @@
 #include "record.h"
 #include "record-y.h"
 
-void record_train_at(Train *tra, int backw, Segment *seg, int maxi, int unc);
+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_step(Train *tra, int step, double speed, int upw, int downw);
-void record_train_step_count(void);
+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);
index e3b588f80544a9e328de82d4daa494937ae80aa2..25193d3b2738cd1a919f92d2f51c36e588a02841 100644 (file)
@@ -44,6 +44,9 @@ line:         /* empty */
        |       TRAIN train IS NUM NUM '+' NUM '+' NUM
        {         if ($2) record_train_is($2,$4,$5,$7,$9);
        }
+       |       TRAIN train AT backwards seg
+       {         if ($2) record_train_at($2,$4,$5);
+       }
        |       TRAIN train AT backwards seg ':' NUM '+' '-' NUM
        {         if ($2) record_train_at($2,$4,$5,$7,$10);
        }
index 6de6dc75a90b8544016d457a507584651ef7ea90..8f05587678a3e452cd76c8af08690d0278e4f878 100644 (file)
@@ -307,7 +307,6 @@ int resolve_complete(void) {
       goto x_problems;
 
     d->iselem_u= 0;
-    d->cm_autostop= 0;
 
     MovPosComb target= -1;
 
index f787355444f69938c0a5f6242f32be7a358caa89..6874a01239f4cbacdca876c4f04e16ee41cb8a6a 100644 (file)
@@ -186,11 +186,10 @@ Segment *segments;
 #define pred_vacated mark2
 #define will_polarise mark3
 
-typedef void PredictionProblemCallback(Train *tra, TrackSegment *seg,
-                                      void *pu, const char *message);
-
 typedef struct {
+  Train *train;
   unsigned
+    count_time:1,
     accelerating:1,
     walk_compute_polarise:1, /* nose_nextseg still needs to worry */
     need_polarise:1, /* when we commit */
@@ -212,7 +211,7 @@ typedef struct {
 
 /*---------- prediction problem reporting ----------*/
 
-static ErrorCode predict_vproblem(PredicUserContext *u, TrackSegment *seg,
+static ErrorCode predict_vproblem(PredictUserContext *u, Segment *seg,
                                  const char *fmt, va_list al) {
   int l;
   char *message;
@@ -220,14 +219,15 @@ static ErrorCode predict_vproblem(PredicUserContext *u, TrackSegment *seg,
   l= vasprintf(&message, fmt, al);  if (l <= 0) diem();
 
   if (!u->problem_callback)
-    safety_panic(u->train, seg, "unexpected problem predicted",
-                " (context: %s): %s", u->problem_callback_u, message);
+    safety_panic(u->train, seg, "unexpected problem predicted"
+                " (context: %s): %s", (char*)u->problem_callback_u, message);
   else
     u->problem_callback(u->train, seg, u->problem_callback_u, message);
 
-  return EC_ProblemPredicted;
+  return EC_SignallingPredictedProblem;
 }
-static ErrorCode predict_problem(PredicUserContext *u, TrackSegment *seg,
+
+static ErrorCode predict_problem(PredictUserContext *u, Segment *seg,
                                  const char *fmt, ...) {
   ErrorCode ec;
   va_list al;
@@ -243,25 +243,28 @@ static int pred_getmovpos(TrackLocation *t, TrackAdvanceContext *c,
                          MovPosComb *use_io) {
   PredictUserContext *u= c->u;
   if (t->seg->motion) *use_io= movpos_change_intent(t->seg->motion);
-  if (*use_io<0) safety_panic(tra,seg, "track route unexpectedly not known");
+  if (*use_io<0) safety_panic(u->train, t->seg,
+                             "track route unexpectedly not known");
   return 0;
 }
 
 static int pred_trackend(TrackLocation *t, TrackAdvanceContext *c) {
-  return predict_problem(t,c,"end of track");
+  PredictUserContext *u= c->u;
+  return predict_problem(u, t->seg, "end of track");
 }
 
 static int pred_trackend_panic(TrackLocation *t, TrackAdvanceContext *c) {
   PredictUserContext *u= c->u;
-  return safety_panic(u->train,t->seg,"unexpected end of track");
+  safety_panic(u->train,t->seg,"unexpected end of track");
 }
 
 static int initpresent_nextseg(TrackLocation *t, TrackAdvanceContext *c,
                               MovPosComb *mpc_io, Segment *before) {
   PredictUserContext *u= c->u;
-  next->now_present= next->pred_present= next->will_polarise= 1;
-  next->until= 0;
+  t->seg->now_present= t->seg->pred_present= t->seg->will_polarise= 1;
+  t->seg->until= 0;
   u->noninv_tally[!t->backwards]++; /* ! since going backwards along train */
+  return 0;
 }
 
 /*---------- prediction nose advancement ----------*/
@@ -269,14 +272,16 @@ static int initpresent_nextseg(TrackLocation *t, TrackAdvanceContext *c,
 static int nose_nextseg(TrackLocation *t, TrackAdvanceContext *c,
                        MovPosComb *mpc_io, Segment *before) {
   PredictUserContext *u= c->u;
+  Segment *interferer;
   MovPosComb route_plan;
-  MovPosChange *route_change;
+  MovPosChange *route_reservation;
   TimeInterval max_ms;
+  ErrorCode ec;
 
   /* Is it empty ? */
 
   if (u->train->sigstopping && t->seg->owner != u->train)
-    return EC_SignalStopHorizonReached;
+    return EC_SignallingHorizonReached;
 
   if (t->seg->owner) {
     if (t->seg->owner != u->train)
@@ -286,7 +291,7 @@ static int nose_nextseg(TrackLocation *t, TrackAdvanceContext *c,
   if (t->seg->pred_present)
     return predict_problem(u, t->seg, "will collide with itself!");
 
-  interferer= interferes(c,t->seg);
+  interferer= segment_interferes(c,t->seg);
   if (interferer) {
     if (interferer->owner && interferer->owner != u->train)
       return predict_problem(u, t->seg, "impeded by %s @%s",
@@ -315,7 +320,7 @@ static int nose_nextseg(TrackLocation *t, TrackAdvanceContext *c,
     /* We already have a plan. */
     route_plan= movpos_change_intent(t->seg->motion);
     if (!u->accelerating) {
-      *mpc_io= route_plan
+      *mpc_io= route_plan;
       goto movement_ok;
     }
   } else {
@@ -378,7 +383,7 @@ static int tail_nextseg(TrackLocation *t, TrackAdvanceContext *c,
 static int fdet_nextseg(TrackLocation *t, TrackAdvanceContext *c,
                        MovPosComb *mpc_io, Segment *before) {
   PredictUserContext *u= c->u;
-  int advanced;
+  int advanced, r;
 
   /* NB, on entry the movposcomb of the segment we're entering (and
    * other similar details) may not be known or sufficient because
@@ -395,9 +400,9 @@ static int fdet_nextseg(TrackLocation *t, TrackAdvanceContext *c,
   u->nosec.distance= advanced;
   r= trackloc_advance(&u->nose,&u->nosec);
 
-  if (r==EC_SignalHorizonReached) {
+  if (r==EC_SignallingHorizonReached) {
     /* stop our prediction now */
-    advanced= was_distance= t->distance= 0;
+    advanced= u->was_distance= t->remain= 0;
     r= 0;
   }
 
@@ -412,7 +417,7 @@ static int fdet_nextseg(TrackLocation *t, TrackAdvanceContext *c,
 
   /* Check polarity */
 
-  if (!t->seg->invertible) {
+  if (!t->seg->i->invertible) {
     u->noninv_tally[t->backwards]++;
     if (u->noninv_tally[0] && u->noninv_tally[1])
       return predict_problem(u, t->seg, "cannot set track polarity");
@@ -442,14 +447,14 @@ static int fdet_nextseg(TrackLocation *t, TrackAdvanceContext *c,
       }
     }
     if (u->know_best_polarity && 
-       !t->seg->i->invertible
+       !t->seg->i->invertible &&
        u->noninv_tally[ t->backwards ^ u->train_polarity_inverted ]) {
       /* incompatible, stop now */
       u->walk_compute_polarise= 0;
     }
   }
   if (u->walk_compute_polarise) {
-    seg->will_polarise= 1;
+    t->seg->will_polarise= 1;
   }
 
   /* Advance the tail */
@@ -473,21 +478,22 @@ static int fdet_nextseg(TrackLocation *t, TrackAdvanceContext *c,
 
 ErrorCode predict_confirm(Train *tra, int accelerate,
                          PredictionProblemCallback *ppc, void *ppcu) {
-  /* Caller must call this with different situations until it succeeds! */
   PredictUserContext u;
   Segment *foredet;
   SEG_IV;
+  ErrorCode ec;
 
   FOR_SEG {
-    seg->now_preset= seg->pred_present=
-      seg->pred_vacated= seg->choose_invert= 0;
+    seg->now_present= seg->pred_present=
+      seg->pred_vacated= seg->will_polarise= 0;
   }
 
   foredet= tra->foredetect;
   
   memset(&u,0,sizeof(u));
+  u.train= tra;
   u.accelerating= accelerate;
-  u.walk_will_polarise= 1;
+  u.walk_compute_polarise= 1;
   u.train_polarity_inverted= foredet->seg_inverted ^ foredet->tr_backwards;
   u.problem_callback= ppc;
   u.problem_callback_u= ppcu;
@@ -503,13 +509,13 @@ ErrorCode predict_confirm(Train *tra, int accelerate,
   u.tailc.trackend= pred_trackend_panic;
   u.tailc.u= &u;
 
-  r= initpresent_nextseg(&u.tail,&u.tailc,0,0);  assert(!r);
-  r= trackloc_advance(&u.tail,&u.tailc);  assert(!r);
+  ec= initpresent_nextseg(&u.tail,&u.tailc,0,0);  assert(!ec);
+  ec= trackloc_advance(&u.tail,&u.tailc);  assert(!ec);
   trackloc_reverse_exact(&u.tail,0);
 
   /* find the train's nose */
 
-  u.nose= fdet;
+  u.nose= u.fdet;
   u.nosec.distance= MARGIN_NOSE + (tra->backwards ? tra->tail : tra->head);
   u.nosec.nextseg= nose_nextseg;
   u.nosec.getmovpos= pred_getmovpos;
@@ -517,8 +523,8 @@ ErrorCode predict_confirm(Train *tra, int accelerate,
   u.nosec.u= &u;
   u.count_time= 0;
 
-  r= trackloc_advance(&u.nose,&u.nosec);
-  if (r) goto xproblem;
+  ec= trackloc_advance(&u.nose,&u.nosec);
+  if (ec) goto xproblem;
 
   /* predict the future */
 
@@ -530,19 +536,11 @@ ErrorCode predict_confirm(Train *tra, int accelerate,
 
   u.tailc.nextseg= tail_nextseg;
 
-  r= trackloc_advance(&fdet,&fdetc);
-  if (r) goto xproblem;
+  ec= trackloc_advance(&u.fdet,&u.fdetc);
+  if (ec) goto xproblem;
 
   /*----- commit to the plan -----*/
 
-  trackloc_set_maxinto(&u.fdet, foredet,
-                      foredet->tr_backwards);
-  u.fdetc.distance= INT_MAX;
-  u.fdetc.nextseg= polarise_nextseg;
-  u.fdetc.trackend= polarise_trackend;
-
-  r= trackloc_advance(&fdet,&fdetc);
-
   if (u.need_polarise)
     actual_inversions_start();
   
@@ -586,11 +584,12 @@ ErrorCode predict_confirm(Train *tra, int accelerate,
       seg->motion= 0;
     }
   }
+  return ec;
 }
 
 /*========== entrypoints from rest of the program ==========*/
 
-static void detection_report_problem(Train *tra, TrackSegment *seg,
+static void detection_report_problem(Train *tra, Segment *seg,
                                     void *pu, const char *message) {
   logmsg("SignallingProblemPredicted",tra,seg->i,
         "re detection @%s: %s", tra->foredetect->i->pname, message);
@@ -598,6 +597,7 @@ static void detection_report_problem(Train *tra, TrackSegment *seg,
 
 void safety_notify_detection(Segment *seg) {
   Train *tra;
+  ErrorCode ec;
   
   if (seg->det_ignore) return;
   if (!seg->det_expected)
@@ -611,16 +611,15 @@ void safety_notify_detection(Segment *seg) {
   ec= predict_confirm(tra, 0, detection_report_problem, 0);
   if (!ec) return;
   
-  assert(ec == EC_SignallingProblemPredicted);
+  assert(ec == EC_SignallingPredictedProblem);
 
   tra->sigstopping= 1;
-  ec= speedmanager_speedchange_request(tra,0, 0,"detection sigstop");
+  ec= speedmanager_speedchange_request(tra,0, 0,(char*)"detection sigstop");
    /* that calls predict_confirm with our supplied arguments */
   assert(!ec);
 }
 
-ErrorCode safety_checkmovposchange(Segment *seg) {
-  ErrorCode ec;
+ErrorCode safety_check_movposchange(Segment *seg) {
   if (seg->owner) {
     oprintf(UPO,"ack SignallingProblemPredicted @%s %s:"
            " route set for approaching train",
index 93863432ee0ac61aabe49da254fe780dbeae164d..e21531bf1acea8f4b6f075ed3e7873cd708f5a92 100644 (file)
@@ -73,7 +73,7 @@ struct Segment {
     moving:1, /* feature(s) have been told to change */
     mark0,mark1,mark2,mark3, /* for temporary private uses */
     res_detect:1; /* detection noticed here during resolution */
-  MovPosComb movposcomb, /* -1 means not known or moving */
+  MovPosComb movposcomb; /* -1 means not known or moving */
   MovPosChange *motion; /* if ->moving, owned by movpos, otherwise by safety */
   TimeInterval until; /* for use by safety.c */
   const SegmentInfo *i;
@@ -101,24 +101,26 @@ void safety_panic(Train *tra, Segment *seg, const char *fmt,...)
  * etc.).
  */
 
-void safety_emergencystop(Train*);
-  /* Callable directly in response to application command. */
+typedef void PredictionProblemCallback(Train *tra, Segment *seg,
+                                      void *pu, const char *message);
 
-ErrorCode safety_requestspeed(Train* tra, long newspeed);
-  /* To be called only by the speed manager, thus indirectly from
-   * user request.  Any error will have been logged.  On success,
-   * ->speed has been updated.  Speed manager is responsible for
-   * calling actual_setspeed.
-   */
-
-void safety_setdirection(Train* tra, int sense_fixme_define_this_properly);
+void safety_setdirection(Train* tra, int backwards);
+  /* NYI */
 
 void safety_notify_detection(Segment *seg);
   /* Called by startup.c when new train detection occurs in state Run. */
 
-ErrorCode safety_checkmovposchange(Segment *seg);
+ErrorCode safety_check_movposchange(Segment *seg);
   /* If this check success, caller may call movpos_change */
 
+ErrorCode predict_confirm(Train *tra, int accelerate,
+                         PredictionProblemCallback *ppc, void *ppcu);
+  /* Lower-level interface for speedmanager etc.
+   * 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.
+   */
+
 /*========== movpos.c ==========*/
 /*
  * movpos.c manages the CDU and points and other moveable features.
@@ -197,23 +199,15 @@ MovPosComb movpos_change_intent(MovPosChange *chg);
   *                       and/or current situation
   */
 
-/*========== speedmgr.c ==========*/
+/*========== speed.c ==========*/
 
-void speedmanager_speedchange_request(Train *tra, long speed);
-  /* Callable directly in response to application command.
-   * speed may be LONG_MAX to mean maximum permitted.
-   */
-
-void speedmanager_emergencystop(Train *tra);
-void speedmanager_autostop(Train *tra);
-  /* These are responsible for calling actual_setspeed.
-   *
-   * After speedmanager_autostop, ->speed will have been updated to a
-   * new desired speed.  If it is 0 the train was going slowly and has
-   * been instructed to stop right now.
-   */
+ErrorCode speedmanager_speedchange_request(Train *tra, int step,
+                           PredictionProblemCallback *ppc, void *ppcu);
+  /* ppc and ppcu as for predict_confirm */
 
 void speedmanager_reset_train(Train *tra);
+double speedmanager_speed_maxestimate(Train *tra);
+double speedmanager_stoppingdistance(Train *tra);
 
 /*========== actual.c ==========*/
 /* actual.c should only be called from safety.c.
@@ -251,20 +245,21 @@ struct TrackLocation { /* transparent, and manipulable by trackloc_... fns */
   unsigned backwards:1; /* if 1, into is positive and measured from end */
 };
 
-void trackloc_set_mininto(TrackLocation *tloc, Segment *seg, int backwards);
 void trackloc_set_maxinto(TrackLocation *tloc, Segment *seg, int backwards);
 
-typedef struct { /* all set by caller, only distance modified by trackloc: */
+typedef struct TrackAdvanceContext {
+  /* all set by caller, only distance modified by trackloc: */
   int distance;
   /* All event callbacks are optional; if not supplied we pretend
    * that they were a no-op which returned 0. */
-  int nextseg(TrackLocation *t, TrackAdvanceContext *c,
-             Segment *next, MovPosComb *mpc_io);
+  int (*nextseg)(TrackLocation *t, struct TrackAdvanceContext *c,
+                MovPosComb *mpc_io, Segment *before);
     /* On entry *mpc_io is from next->movposcomb.  nextseg may modify
      * it if it feels like it in which case the modified value will
      * be used instead.  If on 0-return it is still -1, getmovpos is used.
      * t->remain is not valid on entry and should not be touched. */
-  void getmovpos(TrackLocation *t, TrackAdvanceContext *c, MovPosComb *use_io);
+  int (*getmovpos)(TrackLocation *t, struct TrackAdvanceContext *c,
+                  MovPosComb *use_io);
     /* Will be called                            *use_io on entry is
      *  - at the start of trackloc_advance         value from segment
      *  - after nextseg                            value left by nextseg
@@ -274,7 +269,7 @@ typedef struct { /* all set by caller, only distance modified by trackloc: */
      * -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. */
-  int trackend(TrackLocation *t, TrackAdvanceContext *c);
+  int (*trackend)(TrackLocation *t, struct TrackAdvanceContext *c);
     /* trackloc_advance stops even if this returns 0. */
   void *u;
 } TrackAdvanceContext;
@@ -296,6 +291,10 @@ int trackloc_advance(TrackLocation *t, TrackAdvanceContext *c);
    * returns non-0, or sometimes 0 if we cannot continue and
    * the relevant callback is missing or returned 0. */
 
+int trackloc_reverse_exact(TrackLocation *t, TrackAdvanceContext *c);
+  /* c is used just as for trackloc_getlink.
+   * If we can't determine the movposcombs we call abort. */
+
 /*========== useful macros and declarations ==========*/
 
 /*---------- looping over trains and segments ----------*/
index 516ca74e4246e239a27a34da2a0e002c26fc99cd..d67df9c91770123eb24c213aabbec238b02c79b5 100644 (file)
@@ -8,7 +8,7 @@
 
 static void xmit(Train *tra) {
   Nmra n;
-  enco_nmra_speed126(&n, tra->addr, tra->step, tra->backwards);
+  enco_nmra_speed126(&n, tra->addr, tra->speed.step, tra->backwards);
   retransmit_urgent_requeue(&tra->speed.rn, &n);
 }
 
@@ -18,15 +18,17 @@ static void decel_done(TimeoutEvent *toev) {
 }
 
 static const SpeedRange *stop_info(Train *tra, double speed) {
+  int i;
   for (i=0; i<tra->n_speedregimes; i++)
-    if (speed <= speedregimes[i].speed)
-      return &speedregimes[i];
+    if (speed <= tra->speedregimes[i].speed)
+      return &tra->speedregimes[i];
   abort();
 }
 
 static double current_speed(Train *tra, const struct timeval tnow) {
-  double v1, v2, elapsed;
+  double v1, v2;
   double v1sq, v2sq, vtsq;
+  double left_to_go, ts_v2;
   
   if (tra->speed.try_speed >= 0) return tra->speed.try_speed;
   if (!tra->speed.decel.running) return tra->speed.speed;
@@ -39,26 +41,26 @@ static double current_speed(Train *tra, const struct timeval tnow) {
     return tra->speed.speed= tra->speedcurve[tra->speed.step];
   }
 
-  v2= tra->speed;
+  v2= tra->speed.speed;
   v1= tra->speedcurve[tra->speed.step];
   assert(v2 >= v1);
 
-  ts_v2= stop_info(v2)->ts;
+  ts_v2= stop_info(tra,v2)->ts;
   v1sq= v1*v1;
   v2sq= v2*v2;
   vtsq= v1sq + (v2sq-v1sq) * left_to_go / ts_v2;
   return sqrt(vtsq);
 }
 
-static double speedmanager_speed_maxestimate(Train *tra) {
+double speedmanager_speed_maxestimate(Train *tra) {
   struct timeval tnow;
   mgettimeofday(&tnow);
   return current_speed(tra,tnow) * MARGIN_SPEED;
 }
 
-static double speedmanager_stoppingdistance(Train *tra) {
+double speedmanager_stoppingdistance(Train *tra) {
   struct timeval tnow;
-  double vt;
+  double v, xs;
   const SpeedRange *regime;
   
   mgettimeofday(&tnow);
@@ -66,12 +68,12 @@ static double speedmanager_stoppingdistance(Train *tra) {
 
   if (v==0) return 0;
 
-  regime= stop_info(tra,vt);
+  regime= stop_info(tra,v);
 
   xs= tra->speedregimes[tra->n_speedregimes-1].xs;
 
-  v_ts_vcrit= v * regime->ts;  if (xs > v_ts_vcrit) xs= v_ts_vcrit;
-  xs_vcrit= regime->xs;        if (xs > xs_vcrit)   xs= xs_vcrit;
+  double v_ts_vcrit= v * regime->ts;  if (xs > v_ts_vcrit) xs= v_ts_vcrit;
+  double xs_vcrit= regime->xs;        if (xs > xs_vcrit)   xs= xs_vcrit;
 
   return xs;
 }
@@ -104,15 +106,15 @@ ErrorCode speedmanager_speedchange_request(Train *tra, int step,
 
   if (ec) {
     tra->speed.try_speed= -1;
-    ec2= predict_confirm(tra,1, 0,"abandoned acceleration");
+    ec2= predict_confirm(tra,1, 0,(char*)"abandoned acceleration");
     assert(!ec2);
     return ec;
   }
 
-  tra->step= step;
+  tra->speed.step= step;
   toev_stop(&tra->speed.decel);
-  tra->speed= vtarg;
-  tra->try_speed= -1;
+  tra->speed.speed= vtarg;
+  tra->speed.try_speed= -1;
   xmit(tra);
   return 0;
 }
@@ -126,7 +128,6 @@ void speedmanager_reset_train(Train *tra) {
   tra->speed.decel.callback= decel_done;
   tra->speed.speed= 0;
   tra->speed.try_speed= -1;
-  tra->decelerating= 0;
   if (tra->addr < 0)
     return;
 
index 1808d370c102ab515d09847a6c6b9e380cbd560c..96c589db4eeb160149d410ad439e709981ed7e06 100644 (file)
@@ -5,23 +5,12 @@
 
 #include "realtime.h"
 
-typedef TrackLocationAdvanceCallbacks Calls;
-
 /*---------- constructors/initialisers ----------*/
 
-void trackloc_set_mininto(TrackLocation *tloc, Segment *seg, int backwards) {
-  const SegPosCombInfo *pci;
-
-  tloc->seg= seg;
-  tloc->backwards= backwards;
-  pci= trackloc_segposcomb(tloc);
-  tloc->remain= pci->dist;
-}
-
 void trackloc_set_maxinto(TrackLocation *tloc, Segment *seg, int backwards) {
   tloc->seg= seg;
   tloc->backwards= backwards;
-  tloc->into= 0;
+  tloc->remain= 0;
 }
 
 /*---------- enquirers ----------*/
@@ -31,10 +20,10 @@ int trackloc_getlink(TrackLocation *t, TrackAdvanceContext *c,
                     const SegmentLinkInfo **link_r,
                     MovPosComb mpc) {
   const SegPosCombInfo *pci;
-  MovPosComb mpc;
+  int r;
 
   if (mpc<0)
-    mpc= t->movposcomb;
+    mpc= t->seg->movposcomb;
 
   if (c && c->getmovpos) {
     r= c->getmovpos(t,c,&mpc);
@@ -45,38 +34,42 @@ int trackloc_getlink(TrackLocation *t, TrackAdvanceContext *c,
     *link_r=0;
     return 0;
   }
-  assert(mpc < seg->i->n_poscombs);
-  pci= &seg->i->poscombs[seg->movposcomb];
+  assert(mpc < t->seg->i->n_poscombs);
+  pci= &t->seg->i->poscombs[t->seg->movposcomb];
   if (*pci_r) *pci_r= pci;
-  if (*link_r) *link_r= tloc->backwards ? &pci->backwards : &pci->forwards;
+  if (*link_r) *link_r= &pci->link[t->backwards];
   return 0;
 }
 
 /*---------- mutator ----------*/
 
 int trackloc_advance(TrackLocation *t, TrackAdvanceContext *c) {
-  Segment *next, *save;
+  Segment *next, *leaving;
+  SegmentNum nextnum;
+  const SegPosCombInfo *pci;
   const SegmentLinkInfo *link;
   MovPosComb mpc_nego;
   int leaving_back;
+  int r;
 
-  r= trackloc_getlink(t,c, 0,&link, t->seg.movposcomb);
+  r= trackloc_getlink(t,c, 0,&link, t->seg->movposcomb);
   if (r || !link) return r;
 
   for (;;) {
     if (!c->distance) return 0;
 
     if (t->remain) {
-      use= t->remain < *distance ? t->remain : *distance;
+      int use= t->remain < c->distance ? t->remain : c->distance;
       t->remain -= use;
-      *distance -= use;
+      c->distance -= use;
     } else {
-      next= link->next;
+      nextnum= link->next;
 
-      if (!SOMEP(next)) {
+      if (!SOMEP(nextnum)) {
        if (c->trackend) return c->trackend(t,c);
        return 0;
       }
+      next= &segments[nextnum];
 
       leaving= t->seg;
       leaving_back= t->backwards;
@@ -85,28 +78,34 @@ int trackloc_advance(TrackLocation *t, TrackAdvanceContext *c) {
       mpc_nego= next->movposcomb;
 
       if (c->nextseg) {
-       r= calls->nextseg(t,c, &mpc_nego,leaving);
+       r= c->nextseg(t,c, &mpc_nego,leaving);
        if (r) return r;
       }
 
-      r= trackloc_getlink(t,c, 0,&link, mpc_nego);
+      r= trackloc_getlink(t,c, &pci,&link, mpc_nego);
       if (r || !link) {
        t->seg=leaving;
-       t->seg->backwards= leaving_back;
+       t->backwards= leaving_back;
        return r;
       }
 
-      t->remain= link->dist;
+      t->remain= pci->dist;
     }
   }
 }
 
 static int interfering_movposcomb(TrackAdvanceContext *c, Segment *seg) {
   MovPosComb mpc;
+  int r;
 
-  mpc= t->movposcomb;
+  mpc= seg->movposcomb;
   if (c && c->getmovpos) {
-    r= c->getmovpos(t,c,&mpc);
+    TrackLocation t;
+    t.seg= seg;
+    t.backwards= 0;
+    t.remain= 0;
+
+    r= c->getmovpos(&t,c,&mpc);
     if (r) return 1;
   }
 
@@ -131,71 +130,14 @@ Segment *segment_interferes(TrackAdvanceContext *c, Segment *base) {
   return inter;
 }
 
-/* ============   OLD CODE ============= */
-
-
-
-
-void trackloc_reverse(TrackLocation *tloc);
-  /* Reverses tloc without changing its actual location. */
-
-const SegPosCombInfo *trackloc_segposcomb(const TrackLocation *tloc);
-const SegmentLinkInfo *trackloc_segmentlink(const TrackLocation *tloc,
-                                           const SegPosCombInfo *pci,
-                                           unsigned far);
-
-xxx long trackloc_remaininseg(const TrackLocation *tloc) {
+int trackloc_reverse_exact(TrackLocation *t, TrackAdvanceContext *c) {
   const SegPosCombInfo *pci;
-  long segment_len;
-
-  pci= trackloc_segposcomb(tloc);
-  if (!pci) return -1;
-  segment_len= pci->dist;
-  assert(tloc->into <= segment_len);
-  return segment_len - tloc->into;
-}  
-
-xxx long trackloc_remaininseg_poscomb(const SegPosCombInfo *pci) {
-  segment_len= pci->dist;
-  assert(tloc->into <= segment_len);
-  return segment_len - tloc->into;
-}  
-
+  int r;
   
-void trackloc_reverse_inexact(TrackLocation *tloc) {
-  tloc->remain= trackloc_segmentlink(tloc) - tloc->remain;
-  tloc->backwards ^= 1;
-}
-
-
-int trackloc_further(TrackLocation *tloc, long *remain_io, Segment *err_r) {
-  const SegPosCombInfo *pci;
-  const SegmentLinkInfo *lnki_far;
-  Segment *nextseg;
-  long segment_remain;
-
-
-  if (*remain_io <= segment_remain) {
-    tloc->into += *remain_io;
-    *remain_io= 0;
-    return 0;
-  } else {
-    *remain_io -= segment_remain;
-    tloc->into += segment_remain;
-    pci= trackloc_segposcomb(tloc);
-
-    lnki_far= trackloc_segmentlink(tloc, pci, 0);
-    if (!SOMEP(lnki_far->next)) { *err_r=tloc->seg; return -2; }
-
-    nextseg= &segments[lnki_far->next];
-    if (nextseg->movposcomb<0) { *err_r=nextseg; return -1; }
-
-    tloc->seg= nextseg;
-    tloc->into= 0;
-    tloc->backwards ^= lnki_far->next_backwards;
-    return +1;
-  }
+  r= trackloc_getlink(t,c,&pci,0,-1);
+  if (r) return r;
+  assert(pci);
+  t->remain= pci->dist - t->remain;
+  t->backwards ^= 1;
+  return 0;
 }
-
-
-