chiark / gitweb /
do not panic if host fires a point and then immediately turns off
authorian <ian>
Tue, 15 Apr 2008 01:15:08 +0000 (01:15 +0000)
committerian <ian>
Tue, 15 Apr 2008 01:15:08 +0000 (01:15 +0000)
detpic/morse.messages
detpic/points.asm
hostside/homes.record
hostside/realtime.c
hostside/record-y.y
hostside/record.c
hostside/resolve.c
hostside/safety.c
hostside/safety.h
hostside/speed.c
hostside/trackloc.c

index 8194ad33220c866f0a8636a77757218b14c2c8e5..823df326ca835724c078df4d9873b905325916df 100644 (file)
@@ -96,5 +96,4 @@ PC                                    ; Firing point when CDU empty
 PS     points:pointslave,points:pointmsg ; Firing point on nonexistent board
 PF     ::t                             ; Flash mentions point not on board
 PX                                     ; Host sent >2-byte POINT command
-PQ                                     ; POINTED when already charging
 PA                                     ; POINTED when already firing
index ac50cffe4b97346a5af16aab13a0840e939e5e03..1c5be4a25a33dc3cf65ee27053e233c138d77b68 100644 (file)
@@ -390,7 +390,7 @@ near_gots code
 ;--------------------
 got_pointed @
        tst_f_ifnz cducharging
-       bra     pointed_already_charging
+       return  ; presumably we just turned off
 
        bt_f_if0 pointmsg, 7
        bra     pointed_butnot_firing
@@ -401,7 +401,6 @@ got_pointed @
        goto    serial_addbyte
 
 pointed_butnot_firing panic morse_PA
-pointed_already_charging panic morse_PQ
 
 ;======================================================================
   include final.inc
index 808cb3738d05d9628633b769b3095ec179a53d44..cf8735c0e402322416377346ca251d847ce2cdab 100644 (file)
@@ -1,2 +1,3 @@
 train santafe home -X5
-train shinkansen home -X9 -A5 -A6
+train shinkansen home -X7 -X9 -A5 -A6
+end
index 125a3afe59fcd7c4c9cb101b9c59cf92964cc2fa..fbeb8c5254ff9a9cede20c3786b0bb273edab3be 100644 (file)
@@ -66,11 +66,12 @@ static char *transegn2suffixstring(Train *tra, Segment *seg) {
 
 void vlogmsg(ErrorCode ec, Train *tra, const SegmentInfo *segi,
             const char *fmt, va_list al) {
-  oprintf(UPO, "message %s ", ec ? errorcodelist[ec] : "info");
-  ovprintf(UPO,fmt,al);
-  if (segi || tra) oprintf(UPO, ":");
+  oprintf(UPO, "message %s", ec ? errorcodelist[ec] : "info");
   if (segi) oprintf(UPO, " @%s", segi->pname);
   if (tra) oprintf(UPO, " %s",  tra->pname);
+  if (segi || tra) oprintf(UPO, ":");
+  oprintf(UPO," ");
+  ovprintf(UPO,fmt,al);
   oprintf(UPO, "\n");
 }
 
index 2a3cb7a399888edb58b32f17852db2659377d2da..8d50a682a51f246d856f4ac97112e1afe2ec09b5 100644 (file)
@@ -39,7 +39,7 @@ line:         /* empty */
        |       TRAIN train AT backwards seg ':' NUM '+' '-' NUM
        {         if ($2) record_train_at($2,$4,$5,$7,$10);
        }
-       |       TRAIN train { cur_train=$2; } HOME segments
+       |       TRAIN train HOME { cur_train=$2; } segments
        {
        }
        |       TRAIN train STEP NUM '=' NUM NUM '/' NUM
@@ -53,10 +53,10 @@ line:               /* empty */
        {         if ($2) record_seg_at($2,$4);
        }
 
-backwards:     /* empty */ { return 0; }
-       |       '-' { return 1; }
+backwards:     /* empty */ { $$= 0; }
+       |       '-' { $$= 1; }
 
-segments:      { cur_train= 0; }
+segments:      { cur_train= (void*)-1; }
        |       backwards seg { record_train_home(cur_train,$1,$2); } segments
 ident:         TRAIN | SEG | IS | AT | HAS | STEP | HOME | END | IDENT
 
index 0bd150b733686f31439a6c115045cdb21a87d3e3..363350daa8bdcc94905dd795abded8c1ef86e900 100644 (file)
@@ -312,11 +312,13 @@ static void alloc(void) {
 
 static void parse_file(const char *why) {
   FILE *f;
+  int r;
 
   f= fopen(filename,"r");
   if (!f) diee("config: cannot open %s: %s", why, filename);
   record_yyrestart(f);
-  record_yyparse();
+  r= record_yyparse();
+  assert(!r); /* we're supposed to call yyerror which dies */
 }
 
 static void parse_pass(const char **argv) {
index 14f8aeb35a227cb8bbcba0d35a8e3a0ebb6cab74..cd5cc6a84598d976dec8c23bc7c36a7e0396ad96 100644 (file)
@@ -181,7 +181,7 @@ int resolve_complete(void) {
 
     oprintf(UPO, "resolving  calculate-u\n");
 
-    FOR_SEGMENT(d, NOOP, NOOP) { /* calculate U */
+    FOR_SEGMENT(d,NOOP,NOOP) { /* calculate U */
       unsigned updated= 0;
 
 #define ADDTO_U_EH(homeowner,HH_HE,string)                     \
@@ -296,22 +296,18 @@ int resolve_complete(void) {
 
     MovPosComb target= -1;
 
-    if (d->owner) {
+    if (d->home && d->home->resolution == RR_H) {
+      d->owner= d->home;
+      d->tr_backwards= d->ho_backwards;
+      target= 0; /* a bit kludgey */
+    } else if (d->owner) {
+      d->tr_backwards ^= d->owner->backwards;
+      target= d->movposcomb;
+    }      
+
+    if (d->owner)
       d->until_detect= 1;
-      switch (d->owner->resolution) {
-      case RR_H:
-       d->tr_backwards= d->ho_backwards;
-       target= 0; /* a bit kludgey */
-       break;
-      case RR_E:
-       target= d->movposcomb;
-       d->tr_backwards ^= d->owner->backwards;
-       /* ... we set d->owner->backwards to 0 below, so cancel that out */
-       break;
-      default:
-       abort();
-      }
-    }
+
     if (d->i->n_poscombs>1) {
       d->movposcomb= -1;
       if (target >= 0) {
@@ -323,6 +319,9 @@ int resolve_complete(void) {
          problems++;
        }
       }
+    } else {
+      assert(!d->i->n_movfeats);
+      d->movposcomb= 0;
     }
   }
 
@@ -352,8 +351,27 @@ void resolve_motioncheck(void) {
 
   FOR_SEG {
     if (seg->res_detect) {
-      seg->res_detect= 0;
-      safety_notify_detection(seg);
+      Segment *notify, *onwards;
+      const SegPosCombInfo *pci;
+      const SegmentLinkInfo *link;
+      
+      notify= seg;
+      for (;;) {
+       seg->res_detect= 0;
+       assert(notify->movposcomb >= 0);
+
+       pci= &notify->i->poscombs[notify->movposcomb];
+       link= notify->tr_backwards ? &pci->backwards : &pci->forwards;
+
+       if (!SOMEP(link->next)) break;
+       onwards= &segments[link->next];
+       if (!onwards->res_detect) break;
+       if (onwards->owner != seg->owner) break;
+
+       notify= onwards;
+      }
+      
+      safety_notify_detection(notify);
     }
   }
   
index cca1f991323248174c4b15583620669611a0d319..13d1a1f1bfa8db6201311d03012683497e5b4477 100644 (file)
@@ -82,6 +82,8 @@ static void lay_train_pass(LayTrainState *l,
   long overall, remain, dist_until, time_until;
   int *invert_likehere, train_inverted_here;
   Train *tra= l->tra;
+  const SegPosCombInfo *pci;
+  const SegmentLinkInfo *link;
 
   if (l->ec) return;
 
@@ -89,9 +91,18 @@ static void lay_train_pass(LayTrainState *l,
 
   remain= overall= advance + speed * SPEED_CLEAR_MULT;
 
+fprintf(stderr,"lay_train_pass %s @%s+%ld check_clash=%d"
+       " advance=%ld speed=%ld remain=%ld backwards=%u\n",
+       tra->pname, seg->i->pname, tloc.into,
+       check_clash, advance,speed,remain,
+       backwards);
+
   for (;;) {
     seg= tloc.seg;
 
+fprintf(stderr,"lay_train_pass  loop @%s remain=%ld\n",
+       seg->i->pname, remain);
+
     if (check_clash) {
       lay_train_check_clash(l,seg,seg);
       inter= interferes(seg);
@@ -102,6 +113,9 @@ static void lay_train_pass(LayTrainState *l,
     seg->tr_backwards= tloc.backwards ^ backwards;
     seg->tr_updated= 1;
 
+    if (backwards)
+      seg->until_detect= 0;
+
     train_inverted_here= seg->seg_inverted ^ seg->tr_backwards;
     invert_likehere= &l->invert_count[train_inverted_here];
 
@@ -129,22 +143,29 @@ static void lay_train_pass(LayTrainState *l,
     if (!remain) break;
     int r= trackloc_further(&tloc, &remain);
 
-    if (r==-2) {
+fprintf(stderr,"lay_train_pass   further=%d tloc=@%s+%ld remain=%ld\n",
+       r, tloc.seg->i->pname, tloc.into, remain);
+
+    switch (r) {
+    case -2:
       l->ec= safety_problem(l->tra, seg, "end of track");
       return;
-    }
-    if (r==-1) {
-      l->ec= safety_problem(l->tra, seg, "track route not set");
+    case -1:
+      l->ec= safety_problem(l->tra, tloc.err, "track route not set");
       return;
-    }
-    if (r>1) {
-      const SegPosCombInfo *pci= trackloc_segposcomb(&tloc);
-      const SegmentLinkInfo *link= trackloc_segmentlink(&tloc,pci,0);
+    case +1:
+      pci= trackloc_segposcomb(&tloc);
+      link= trackloc_segmentlink(&tloc,pci,0);
       if (link->next+segments != seg) {
        l->ec= safety_problem(l->tra, link->next+segments,
                              "track route set against us");
        return;
       }
+      break;
+    case 0:
+      return;
+    default:
+      abort();
     }
   }
 }
@@ -165,6 +186,8 @@ static void lay_train_inversions(LayTrainState *l) {
     assert(seg->owner == l->tra);
     seg_be_inverted= train_be_inverted ^ seg->tr_backwards;
     assert(!(seg_be_inverted && !segi->invertible));
+    if (!segi->invertible)
+      continue;
     seg->seg_inverted= seg_be_inverted;
     actual_inversions_segment(seg);
   }
@@ -194,7 +217,12 @@ static ErrorCode lay_train(Train *tra, long added_slop) {
 
   tloc.seg= seg;
   tloc.into= tra->maxinto;
-  tloc.backwards= seg->tr_backwards ^ tra->backwards;
+  tloc.backwards= seg->tr_backwards;
+
+fprintf(stderr,"lay_train %s @%s added_slop=%ld maxinto=%ld "
+       "tra->backwards=%d tloc.backwards=%d\n",
+       seg->i->pname, tra->pname, added_slop, (long)tra->maxinto,
+       tra->backwards, tloc.backwards);
 
   l.tra= tra;
   l.ec= 0;
@@ -222,7 +250,7 @@ static ErrorCode lay_train(Train *tra, long added_slop) {
   trackloc_reverse(&tloc);
   seg->tr_updated= 0; /* we're about to do this one again */
   tail= tra->backwards ? tra->head : tra->tail;
-  taildet= tra->detectable + tail;
+  taildet= tra->detectable + tail + tra->maxinto;
 
   lay_train_pass(&l, tloc, taildet,   0,          1, 1);
 
@@ -263,10 +291,10 @@ void safety_notify_detection(Segment *seg) {
   }
   tra->uncertainty= tra->maxinto;
 
-  if (!(tra->estopping || tra->speed==0)) {
+  if (!tra->estopping) {
     ec= lay_train(tra, 0);
     if (ec) {
-      logmsg(ec,tra,seg->i, "emergency stop");
+      logmsg(ec,tra,seg->i, "emergency stop on reaching here");
       safety_emergencystop(tra);
     }
   }
index 4d895a434f798956a698891c4f22cff1ce5ee200..4d22969ab40110ee851f9bfde6505606bd63123f 100644 (file)
@@ -234,20 +234,24 @@ void actual_inversions_done(void);
 typedef struct TrackLocation TrackLocation;
 struct TrackLocation { /* transparent, and manipulable by trackloc_... fns */
   Segment *seg; /* current segment */
+  Segment *err; /* segment where error happens (eg, movposcomb wrong) */
   long into; /* distance from start of segment */
   unsigned backwards:1; /* if 1, into is positive and measured from end */
 };
 
 long trackloc_remaininseg(const TrackLocation *tloc);
-  /* Returns dist that tloc can advance before it goes into next segment. */
+  /* Returns dist that tloc can advance before it goes into next segment.
+   * Returns -1 if current track log has unknown movposcomb.
+   */
 
 int trackloc_further(TrackLocation *tloc, long *remain_io);
   /* Advances tloc, decrementing *remain_io, until one of the
-   * following happens:
-   *    tloc->segn changes               returns +1
-   *    *remain_io becomes zero          returns  0
-   *    unknown movpos found             returns -1
-   *    end of track reached             returns -2
+   * following happens:                                        err set to
+   *    tloc->segn changes                      returns +1      unchanged
+   *    *remain_io becomes zero                 returns  0      unchanged
+   *    unknown movpos found                    returns -1      next segment
+   *    end of track reached                    returns -2      seg
+   *    current track segment unknown movpos!   returns -3      seg
    * Does _not_ check that the movposcomb of the segment we
    * are moving into is correct.
    */
index 336d87b633bf41babf5833d5192735dfd812e5e8..83befdc66da3cc74bde8e7eb3a8ad695ca5d73e8 100644 (file)
@@ -11,17 +11,16 @@ static void accel_more(TimeoutEvent *toev);
 
 void speedmanager_reset_train(Train *tra) {
   Nmra n;
-  ErrorCode ec;
   
   tra->estopping= 0;
   tra->speed= 0;
   tra->accel.target= tra->accel.commanded= 0;
+  if (tra->addr < 0)
+    return;
+
   toev_init(&tra->accel.more);
   enco_nmra_speed126(&n, tra->addr, 0, tra->backwards);
   retransmit_urgent_queue_relaxed(&tra->accel.rn, &n);
-  ec= safety_requestspeed(tra, 0);
-  if (ec)
-    safety_panic(tra, 0, "position reset impossible!");
 }
 
 static void xmit_speed(Train *tra) {
@@ -44,8 +43,12 @@ void speedmanager_autostop(Train *tra) {
 
 static void estop_done(TimeoutEvent *toev) {
   Train *tra= (void*)((char*)toev - offsetof(Train, accel.more));
+  ErrorCode ec;
   retransmit_urgent_cancel(&tra->accel.rn);
   speedmanager_reset_train(tra);
+  ec= safety_requestspeed(tra, 0);
+  if (ec)
+    safety_panic(tra, 0, "position reset impossible!");
 }
  
 void speedmanager_emergencystop(Train *tra) {
@@ -132,6 +135,11 @@ void speedmanager_speedchange_request(Train *tra, long speed) {
   int a, b, try, found;
   const SpeedCurveEntry *curve= tra->accel.curve;
 
+  if (tra->addr < 0) {
+    logmsg(EC_Invalid, tra, 0, "speed request ignored, train address unknown");
+    return;
+  }
+
   if (tra->estopping) {
     logmsg(EC_Invalid, tra, 0, "speed request ignored during emergency stop");
     return;
index 4d0ba11a73647382f6cde617301c891ed54ce5ff..20c6770f471505b27a8bee8642b39fa607a7e28d 100644 (file)
@@ -16,7 +16,7 @@ const SegPosCombInfo *trackloc_segposcomb(const TrackLocation *tloc) {
 const SegmentLinkInfo *trackloc_segmentlink(const TrackLocation *tloc,
                                            const SegPosCombInfo *pci,
                                            unsigned far) {
-  return (tloc->backwards ^ far) ? &pci->backwards : &pci->forwards;
+  return (tloc->backwards ^ far) ? &pci->forwards : &pci->backwards;
 }
 
 long trackloc_remaininseg(const TrackLocation *tloc) {
@@ -24,6 +24,7 @@ long trackloc_remaininseg(const TrackLocation *tloc) {
   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;
@@ -32,9 +33,11 @@ long trackloc_remaininseg(const TrackLocation *tloc) {
 int trackloc_further(TrackLocation *tloc, long *remain_io) {
   const SegPosCombInfo *pci;
   const SegmentLinkInfo *lnki_far;
+  Segment *nextseg;
   long segment_remain;
 
   segment_remain= trackloc_remaininseg(tloc);
+  if (segment_remain<0) { tloc->err=tloc->seg; return -3; }
 
   if (*remain_io <= segment_remain) {
     tloc->into += *remain_io;
@@ -44,10 +47,14 @@ int trackloc_further(TrackLocation *tloc, long *remain_io) {
     *remain_io -= segment_remain;
     tloc->into += segment_remain;
     pci= trackloc_segposcomb(tloc);
-    if (!pci) return -1;
+
     lnki_far= trackloc_segmentlink(tloc, pci, 1);
-    if (!SOMEP(lnki_far->next)) return -2;
-    tloc->seg= &segments[lnki_far->next];
+    if (!SOMEP(lnki_far->next)) { tloc->err=tloc->seg; return -2; }
+
+    nextseg= &segments[lnki_far->next];
+    if (nextseg->movposcomb<0) { tloc->err=nextseg; return -1; }
+
+    tloc->seg= nextseg;
     tloc->into= 0;
     tloc->backwards ^= lnki_far->next_backwards;
     return +1;