static PointQueue pt_confirmed, pt_reserved;
static void pt_check_action(void);
+static ErrorCode pt_check_plan(void);
static PtSlot pt_maxdelay_reldeadline(int maxdelay_ms) {
+ if (maxdelay_ms==-1) return PT_MAX_QUEUE*16;
return (maxdelay_ms - POINT_MOVEMENT + CDU_RECHARGE) / CDU_RECHARGE;
}
pt_queue_remove_item(&pt_confirmed, r);
} else if (~r->deadline) {
pt_queue_remove_item(&pt_reserved, r);
+ } else {
+ return;
}
+ pt_check_plan();
}
static void pt_mark_as_allocated(PointReq *r) { /* AX->X */
r->motions[0].i=0;
}
+#define WHICH(wh) \
+ (whichr= wh##r, \
+ whichwhen= wh##when, \
+ wh++)
+
static ErrorCode pt_check_plan(void) {
/* Checks whether we can meet the currently queued commitments */
- int future, conf, resv, usewhen;
-
- fixme there is something wrong as
- INT_MAX maxdelay_ms should not work as it overflows and makes
- negative deadlines
-
-debug movpos/change : A5/P0 maxdelay_ms=2147483647 actual=?
- point allocate 1
-debug movpos/change-needed : point:P(2*1) -1<-0 => 1debug movpos/change : confirm point:1...
-debug movpos/point : confirm A5 n=1 maxdelay=2147483647 (res: n=1 deadline=[t+]-1)
-debug movpos/point : newdeadline=t+-8589933 allow_failure=1
- pt_enqueue
-debug movpos/point : pt_enqueue=OK
-movpos A5 position ? moving
-debug movpos/change : confirm => OK
+ int future, conf, resv, whichwhen;
+ PointReq *whichr;
conf=resv=0;
+ future=0;
- /* If CDU is charged we can do one thing right away */
- while (conf < pt_confirmed.n &&
- pt_confirmed.l[0]->deadline==pt_cslot) {
- if (!pt_cdu_charged) return EC_MovFeatTooLate;
- if (conf) return EC_MovFeatTooLate;
- conf++;
+ oprintf(DUPO("movpos/point") " plan");
+
+ /* If CDU is charged we can't do one right away */
+ if (!pt_cdu_charged) {
+ oprintf(UPO, " +");
+ future++;
}
- future=1;
for (;;) {
PointReq *confr= conf < pt_confirmed.n ? pt_confirmed.l[conf] : 0;
PointReq *resvr= resv < pt_reserved .n ? pt_reserved .l[conf] : 0;
if (!confr && !resvr) break;
+ oprintf(UPO," %d:",future);
int confwhen= confr ? confr->deadline - pt_cslot : INT_MAX;
int resvwhen= resvr ? resvr->deadline : INT_MAX;
- if (resvwhen < confwhen) {
- usewhen= resvwhen;
- resv++;
+ if (future && resvwhen < confwhen) {
+ WHICH(resv);
+ oprintf(UPO,"~");
+ } else if (confr) {
+ WHICH(conf);
} else {
- usewhen= confwhen;
- conf++;
+ oprintf(UPO,"-");
+ future++;
+ continue;
}
- if (usewhen > future) return EC_MovFeatTooLate;
- future++;
+ oprintf(UPO, "%s/%s[%d@t+%d]", whichr->h.move->i->pname,
+ posnpname(whichr->h.move, whichr->h.intent),
+ whichr->n_motions, whichwhen);
+ if (future > whichwhen) {
+ oprintf(UPO,"!...bad\n");
+ return EC_MovFeatTooLate;
+ }
+ future += whichr->n_motions;
}
+ oprintf(UPO," ok\n");
return 0;
}
+#undef WHICH
+
static ErrorCode pt_enqueue(PointQueue *q, PointReq *r) { /* XA -> X */
int insat; /* ... where X is R or C and corresponds to q */
/* or on error, XA -> A */
return EC_BufferFull;
}
-fprintf(stderr," pt_enqueue\n");
for (insat= q->n;
insat>0 && (PtSlotSigned)(r->deadline - q->l[insat-1]->deadline) < 0;
insat--)
static Change *point_allocate(int alloc_motions) {
PointReq *r;
-fprintf(stderr," point allocate %d\n",alloc_motions);
assert(pt_cdu_charged>=0);
if (!alloc_motions)
/* we need at least one motion in the table so we can tell
int allow_failure;
ErrorCode ec;
- oprintf(DUPO("movpos/point") "confirm %s n=%d maxdelay=%d"
- " (res: n=%d deadline=[t+]%d)\n",
+ oprintf(DUPO("movpos/point") "confirm %s n=%d maxdelay=%dms"
+ " (res: [%d@t+%d])\n",
move->i->pname, n_motions, maxdelay_ms,
r->n_motions, r->deadline);
assert(n_motions <= r->n_motions);
if (maxdelay_ms == -1) {
newdeadline= r->deadline;
+ if (!~newdeadline) newdeadline= pt_maxdelay_reldeadline(-1);
} else {
newdeadline= pt_maxdelay_reldeadline(maxdelay_ms);
}
allow_failure= newdeadline < r->deadline;
- oprintf(DUPO("movpos/point") " newdeadline=t+%d allow_failure=%d\n",
- newdeadline, allow_failure);
+ oprintf(DUPO("movpos/point") " newdeadline=[%d@t+%d] allow_failure=%d\n",
+ n_motions, newdeadline, allow_failure);
newdeadline += pt_cslot;
/* state A or R */
static void pt_check_action(void) {
PicInsn piob;
+ ErrorCode ec;
if (!pt_confirmed.n) {
if (sta_state == Sta_Finalising) resolve_motioncheck();
oprintf(UPO, "movpos %s point %s%d\n", r->h.move->i->pname,
m->i->pname, m->posn);
pt_cdu_charged= 0;
+ pt_cslot++;
MovPosComb above_weight= m->i->weight * m->i->posns;
MovPosComb above= r->actual / above_weight;
pt_mark_as_allocated(r); /* now state A aka Done */
motion_done(move,r->h.actual);
free(r);
+ ec= pt_check_plan(); assert(!ec);
pt_check_action();
}
}
int r;
r= startpoint<0 ||
(target - startpoint) / feati->weight % feati->posns;
- oprintf(DUPO("movpos/change-needed") "%s:%s(%d*%d) %d<-%d => %d",
+ oprintf(DUPO("movpos/change-needed") "%s:%s(%d*%d) %d<-%d => %d\n",
methodinfos[feati->kind].pname, feati->pname,
feati->posns, feati->weight,
target, startpoint, r);
actual= move->motion->actual;
}
- oprintf(DUPO("movpos/change") "%s/%s maxdelay_ms=%d actual=%s\n",
+ oprintf(DUPO("movpos/change") "%s/%s maxdelay=%dms actual=%s\n",
move->i->pname, posnpname(move,target),
maxdelay_ms, posnpname(move, actual));
if (chg) oprintf(DUPO("movpos/change") " chg=%s:%s/%s\n",
ErrorCode ec;
int nchanges;
- oprintf(DUPO("movpos/reserve") "%s/%s maxdelay_ms=%d startpoint=%s\n",
+ oprintf(DUPO("movpos/reserve") "%s/%s maxdelay=%dms startpoint=%s\n",
move->i->pname, posnpname(move,target),
maxdelay_ms, posnpname(move,startpoint));
u->nosec.distance= advanced;
r= trackloc_advance(&u->nose,&u->nosec);
if (r == EC_SignallingHorizonReached &&
- u->was_distance==INT_MAX) {
+ u->was_distance==TL_DIST_INF) {
/* 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. */
return predict_problem(u, t->seg, "cannot set track polarity");
}
- if (u->was_distance == INT_MAX) {
+ if (u->was_distance == TL_DIST_INF) {
t->seg->det_expected= 1;
u->walk_compute_polarise= u->need_polarise=
/* Final adjustments, prepare for next iteration */
- if (u->was_distance == INT_MAX)
+ if (u->was_distance == TL_DIST_INF)
c->distance= speedmanager_stoppingdistance(u->train);
u->was_distance= c->distance;
u.tail.remain= 0;
u.tail.backwards= !u.tail.seg->tr_backwards;
- u.tailc.distance= INT_MAX;;
+ u.tailc.distance= TL_DIST_INF;;
u.tailc.nextseg= report_nextseg;
u.tailc.getmovpos= pred_getmovpos;
u.tailc.u= &u;
/* predict the future */
- u.fdetc.distance= u.was_distance= INT_MAX;
+ u.fdetc.distance= u.was_distance= TL_DIST_INF;
u.fdetc.nextseg= fdet_nextseg;
u.fdetc.getmovpos= pred_getmovpos;
u.fdetc.trackend= pred_trackend;