From: ian Date: Sun, 27 Jul 2008 20:25:46 +0000 (+0000) Subject: New resolution arrangements; before move predict() call into resolve_motioncheck X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ijackson/git?a=commitdiff_plain;h=80341f1c1257cc81f37f536e9b15b64b1f44452b;p=trains.git New resolution arrangements; before move predict() call into resolve_motioncheck --- diff --git a/hostside/resolve.c b/hostside/resolve.c index 6a29ab7..dc093bc 100644 --- a/hostside/resolve.c +++ b/hostside/resolve.c @@ -382,12 +382,22 @@ static int resolve_complete_main(void) { /*---------- heads and tails of trains, final placement ----------*/ #define resfin_ours mark1 -#define resfin_done mark2 typedef struct { + Distance hardallow, min, max; + int hardwhy; + Segment *lastdetect, *hardend; +} FindEndConstraint; + +typedef struct { + TrackAdvanceContext tc; /* first! */ + TrackLocation t; Train *train; - Segment *furthest; - int extraspace; + Segment *startpoint; + Distance atlastdetect; + Segment *lastdetect; + FindEndConstraint constraints[2]; + int problems, rear; } FindEndUserContext; static int findends_getmovpos(TrackLocation *t, TrackAdvanceContext *c, @@ -395,75 +405,125 @@ static int findends_getmovpos(TrackLocation *t, TrackAdvanceContext *c, const char *pn= t->seg->i->pname; if (t->seg->motion) *use_io= movpos_change_intent(t->seg->motion); if (*use_io<0) { - DPRINTF(resolving,ends, " getmovpos %s fails\n", pn); - t->seg->resfin_done= 0; - return -1; + DPRINTF(resolving,ends, " getmovpos %s fails\n", pn); + return 'm'; } - DPRINTF(resolving,ends, " getmovpos %s -> %d\n", pn, *use_io); + DPRINTF(resolving,ends, " getmovpos %s -> %d\n", pn, *use_io); return 0; } -static int segdist(Segment *seg) { - TrackLocation t; +static int constraint_nextseg(TrackLocation *t, struct TrackAdvanceContext *c, + MovPosComb *mpc, const TrackLocation *before) { int r; - MovPosComb mpc; - - t.seg= seg; - mpc= seg->movposcomb; + FindEndUserContext *u= (void*)c; - r= findends_getmovpos(&t,0,&mpc); - assert(!r); assert(mpc >= 0); - return seg->i->poscombs[mpc].dist; -} - -static void ends_callback_debug(const char *what, TrackLocation *t, - struct TrackAdvanceContext *c) { - DPRINTF(resolving,ends, " %s" - " %s%s dist=%d det=%d ours=%d done=%d owner=%s home=%s\n", - what, t->backwards?"-":"", t->seg->i->pname, c->distance, + DPRINTF(resolving,ends, " constraint_nextseg %c" + " %s%s dist=INF-%d det=%d ours=%d owner=%s home=%s\n", + "fr"[u->rear], + t->backwards?"-":"", t->seg->i->pname, + TL_DIST_INF - c->distance, t->seg->res_detect, t->seg->resfin_ours, - t->seg->resfin_done, t->seg->owner ? t->seg->owner->pname : "-", t->seg->home ? t->seg->home->pname : "-"); -} -static int findhead_nextseg(TrackLocation *t, struct TrackAdvanceContext *c, - MovPosComb *mpc_io, const TrackLocation *before) { - FindEndUserContext *u= c->u; + if (!t->seg->resfin_ours) return 'o'; + r= findends_getmovpos(t,0,mpc); if (r) return r; - ends_callback_debug("findhead_nextseg",t,c); + const SegPosCombInfo *pci= &t->seg->i->poscombs[*mpc]; - if (!t->seg->resfin_ours || t->seg->resfin_done) return -1; - u->furthest= t->seg; - t->seg->tr_backwards= t->backwards; - t->seg->resfin_done= 1; - - if (!t->seg->res_detect) { - u->train->plan_lookahead_nsegs= 1; - u->extraspace= 0; - return -1; + if (before) { + if (t->seg == u->startpoint) return 'l'; + const SegmentLinkInfo *rlink= &pci->link[!t->backwards]; + if (before->seg != &segments[rlink->next]) return 'm'; + } + if (t->seg->res_detect) { + u->atlastdetect= c->distance; + u->lastdetect= t->seg; } - u->train->foredetect= t->seg; return 0; } -static int walkback_nextseg(TrackLocation *t, struct TrackAdvanceContext *c, - MovPosComb *mpc_io, const TrackLocation *before) { - ends_callback_debug("walkback_nextseg",t,c); +static int constraint_trackend(TrackLocation *t, + struct TrackAdvanceContext *c) { + return 'e'; +} - if (!t->seg->resfin_ours) return -1; - t->seg->tr_backwards= !t->backwards; - t->seg->resfin_done= 1; - return 0; +static void end_startpoint(FindEndUserContext *u) { + int r; + + u->tc.distance= TL_DIST_INF; + u->tc.nextseg= constraint_nextseg; + u->tc.getmovpos= findends_getmovpos; + u->tc.trackend= constraint_trackend; + u->tc.u= 0; + + r= trackloc_set_exactinto(&u->t, &u->tc, + u->startpoint, u->startpoint->tr_backwards, + 0); + assert(!r); +} + +static void end_constraints(FindEndUserContext *u) { + FindEndConstraint lim; + Train *tra= u->train; + int r; + + end_startpoint(u); + u->tc.distance= TL_DIST_INF; + + u->lastdetect= 0; + u->atlastdetect= -1; + + if (u->rear) { + r= trackloc_reverse_exact(&u->t,&u->tc); + assert(!r); + } + + FindEndConstraint *cons= &u->constraints[u->rear]; + + cons->hardwhy= trackloc_advance(&u->t,&u->tc); + + assert(cons->hardwhy); + assert(u->lastdetect); + assert(u->atlastdetect >= 0); + + Distance nose= MARGIN_NOSE + + ((tra->backwards ^ u->rear) ? tra->head : tra->tail); + + lim.min= TL_DIST_INF - u->atlastdetect; + lim.max= (TL_DIST_INF - u->tc.distance) - nose; + + if (!u->rear) { + cons->min= lim.min; + cons->max= lim.max; + } else { + cons->max= -lim.min + tra->detectable; + cons->min= -lim.max + tra->detectable; + } + cons->lastdetect= u->lastdetect; + cons->hardend= u->t.seg; + + if (cons->min > cons->max) { + ouprintf("resolution implausible %s %s overhang %d %d\n", + cons->lastdetect->i->pname, tra->pname, + cons->min - cons->max, nose); + u->problems++; + } + + DPRINTF(resolving,ends, " lims %c hardwhy=%c %s,%s lim=%d..%d out=%d..%d\n", + "fr"[u->rear], cons->hardwhy, + cons->lastdetect->i->pname, u->t.seg->i->pname, + lim.min, lim.max, cons->min, cons->max); } static int resolve_complete_ends_train(Train *tra) { SEG_IV; - TrackLocation t; - TrackAdvanceContext tc; FindEndUserContext u; - Segment *startpoint; + const SegPosCombInfo *pci; + struct timeval tnow; + ErrorCode ec; + int r, DP; switch (tra->resolution) { case RR_H: break; @@ -472,91 +532,87 @@ static int resolve_complete_ends_train(Train *tra) { default: abort(); } - DPRINTF(resolving,ends, "%s %c\n", - tra->pname, RESOLUTION_CHARS[tra->resolution]); + DPRINTF1(resolving,ends, "%s %c", + tra->pname, RESOLUTION_CHARS[tra->resolution]); - startpoint= 0; + memset(&u,0,sizeof(u)); + u.startpoint= 0; FOR_SEGMENT(seg,NOOP,NOOP) { - seg->resfin_done= 0; seg->resfin_ours= tra == (tra->resolution==RR_H ? seg->home : seg->owner); - if (seg->resfin_ours && seg->res_detect) - startpoint= seg; + if (!seg->resfin_ours) continue; + DPRINTF2(" %s%s", seg->tr_backwards?"-":"", seg->i->pname); + if (seg->res_detect) { + DPRINTF2("*"); + u.startpoint= seg; + } } - - assert(startpoint); - - t.seg= startpoint; - t.remain= 0; - t.backwards= t.seg->tr_backwards ^ tra->backwards; - - tra->backwards= 0; - tra->plan_lookahead_nsegs= 0; - - tc.distance= TL_DIST_INF; - tc.nextseg= findhead_nextseg; - tc.getmovpos= findends_getmovpos; - tc.trackend= 0; - tc.u= &u; + assert(u.startpoint); + DPRINTF2("\n"); + + /* There are four pieces of information we have: + * The rearmost detection, the rearmost end of ownership + * the foremost detection, the foremost end of ownership + * + * From each we compute a range of locations. These are + * in the form of a minimum and maximum distance of the + * foredetect ahead of 0 into the startpoint. + */ u.train= tra; - u.extraspace= MARGIN_NOSE + tra->head; - u.furthest= 0; - - DPRINTF(resolving,ends, " start=%s%s es=%d\n", - t.backwards?"-":"", t.seg->i->pname, u.extraspace); - - trackloc_advance(&t,&tc); + for (u.rear=0; u.rear<2; u.rear++) + end_constraints(&u); - DPRINTF(resolving,ends, " es=%d furthest=%s fd=%s%s fd.dist=%d\n", - u.extraspace, u.furthest->i->pname, - tra->foredetect->tr_backwards?"-":"", tra->foredetect->i->pname, - segdist(tra->foredetect)); + Distance wrongness; - tra->maxinto= segdist(tra->foredetect) - u.extraspace; - if (tra->maxinto < 0) { - ouprintf("resolution mispositioned head %s %s %d\n", - tra->pname, tra->foredetect->i->pname, -tra->maxinto); - return 1; + if ((wrongness= u.constraints[0].min - u.constraints[1].max) > 0) { + for (u.rear=1; u.rear>0; u.rear--) + ouprintf("resolution implausible %s %s over-detect %d\n", + u.constraints[u.rear].lastdetect->i->pname, + tra->pname, wrongness); + u.problems++; } - tra->uncertainty= tra->maxinto; + if ((wrongness= u.constraints[1].min - u.constraints[0].max) > 0) { + for (u.rear=1; u.rear>0; u.rear--) + ouprintf("resolution implausible %s %s cramped %d\n", + u.constraints[u.rear].hardend->i->pname, + tra->pname, wrongness); + u.problems++; + } + + int min= MIN(u.constraints[0].min, u.constraints[1].min); + int max= MIN(u.constraints[0].max, u.constraints[1].max); + DPRINTF(resolving,ends, " lims a %d..%d problems=%d\n", + min, max, u.problems); - t.seg= tra->foredetect; - t.remain= 0; - t.backwards= !tra->foredetect->tr_backwards; + if (u.problems) + return u.problems; - tc.distance= tra->detectable + tra->tail + MARGIN_NOSE; - tc.nextseg= walkback_nextseg; + assert(min <= max); + assert(max > 0); /* startpoint is detected so foredet is there or later */ - trackloc_advance(&t,&tc); + /* Now we just need to turn this into the canonical format. */ - DPRINTF(resolving,ends, " maxi=%d unc=%d;" - " remaining distance=%d\n", - tra->maxinto, tra->uncertainty, tc.distance); + end_startpoint(&u); - if (tc.distance) { - tra->uncertainty -= tc.distance; - if (tra->uncertainty < 0) { - ouprintf("resolution mispositioned tail %s %s %d\n", - tra->pname, t.seg->i->pname, -tra->uncertainty); - return 1; - } - } + u.tc.distance= max; + r= trackloc_advance(&u.t, &u.tc); assert(!r); - FOR_SEG { - if (seg->owner == tra) - seg->owner= 0; + tra->foredetect= u.t.seg; + tra->foredetect->tr_backwards= u.t.backwards; - if (seg->resfin_done) { - seg->owner= tra; - seg->resfin_done= 0; - seg->det_ignore= 1; - } - } + r= trackloc_getlink(&u.t, &u.tc, &pci,0,0); assert(!r); + tra->maxinto= pci->dist - u.t.remain; + tra->uncertainty= max - min; report_train_position(tra); - report_train_ownerships(tra, t.seg, 1); + + mgettimeofday(&tnow); + tra->plan_lookahead_nsegs= INT_MAX; + ec= predict(tra,tnow, PREDF_OLDPLAN, 0,0, 0, + 0,(char*)"resolution confirmation"); + assert(!ec); return 0; }