public Diversion :: -- routes : set of seq of Network`EdgeId;
route : [seqofchar];
public TrafficLight ::
on: bool
greentime : nat;
public RampMeter ::
redtime : nat;
public HardShoulder ::
open : bool;
public LaneClosure ::
closed : nat;
public Control = map Network`EdgeId tosetof TCM;
-- The ActControl is different from Control in that it also contains information about the requestor so -- it can be removed when no longer needed... public ActControl = map Network`EdgeId tosetof (Network`EdgeId * TCM);
public Bridges = map Network`EdgeId to Bridge;
public Priorities = map Network`EdgeId to Priority;
public LeadsTo = map Network`EdgeId tosetof Network`EdgeId;
values -- TODO Define values here instancevariables
myid: seqofchar;
leadsto: LeadsTo := {|->};
network: Network;
myedges : setof Network`EdgeId; -- ids must be edge ids that this TMS control
interestededges : setof Network`EdgeId; --those additional edges I would like to get information about inv TMSInv(myedges, interestededges); -- Tom-Tom TMSs would have no edges to control but would have all edges as interestededges -- and as a consequence can give advice to their cars of better routes given the new TMCs
control : Control := {|->}; -- these are the possible TCMs for each edge
actctrl : ActControl := {|->}; -- these are the actual TCMs for each edge --inv forall tcm in set dunion rng actctrl & is_MaxSpeed(tcm) => tcm.speed <> nil;
bridges : Bridges := {|->}; -- this maps specifies which edges have a bridge
trafsit : Environment`TrafficSituation := {|->};
trigger: Control := {|->}; -- these are the new TCMs being triggered in this step
prios: Priorities := {|->}; invdom trigger subsetdom control; invdom actctrl subsetdom control; invdom control subset myedges;
public negos: int := 0; public acceptedoffers: int := 0; public averagedensity: real :=0; public densityperedge: map Network`EdgeId toreal := {|->}; public averagevelocity: real :=0; public velocityperedge: map Network`EdgeId toreal := {|->};
internaledges : map Network`EdgeId tosetof Network`EdgeId;
world : World;
public CalculateInterest: Network ==> ()
CalculateInterest(n) == ( dcl interest: setof Network`EdgeId := {}; forall eid inset myedges do interest := interest union n.OfInterestTo(eid);
interestededges := interest \ myedges
);
RecordDensityVelocity: Environment`TrafficSituation ==> ()
RecordDensityVelocity(ts) ==
(dcl accumulatingdensity: real :=0,
accumulatingvelocity: real :=0; forall eid inset myedges dolet mk_(d,v,-,-,-) = ts(eid) in
(accumulatingdensity := accumulatingdensity + d;
accumulatingvelocity := accumulatingvelocity + v; if eid insetdom densityperedge then densityperedge(eid) := d else densityperedge := densityperedge munion {eid|->d}; if eid insetdom velocityperedge then velocityperedge(eid) := v else velocityperedge := velocityperedge munion {eid|->v}
);
averagedensity := accumulatingdensity/card myedges;
averagevelocity := accumulatingvelocity/card myedges;
);
GenerateMyOwnTriggers: Environment`TrafficSituation ==> ()
GenerateMyOwnTriggers(ts) ==
(oldproblematicedges := problematicedges;
problematicedges := {};
RecordDensityVelocity(ts); -- Done for visulisation purposes.
(forall eid insetdom control do let tcm_s = control(eid) in
(IO`printf("Controls avaliable for %s: %s\n",[eid,tcm_s]); if tcm_s <> {} then (ifexists tcm inset tcm_s & is_HardShoulder(tcm) then trigger(eid) := if eid insetdom trigger then AddTrig(trigger(eid),SetHardShoulder(eid, ts(eid))) else AddTrig({},SetHardShoulder(eid, ts(eid))); ifexists tcm inset tcm_s & is_LaneClosure(tcm) then trigger(eid) := if eid insetdom trigger then AddTrig(trigger(eid),SetLaneClosure(eid, ts(eid))) else AddTrig({},SetLaneClosure(eid, ts(eid))); ifexists tcm inset tcm_s & is_MaxSpeed(tcm) then trigger(eid) := if eid insetdom trigger then AddTrig(trigger(eid),SetMaxSpeed(eid, ts(eid))) else AddTrig({},SetMaxSpeed(eid, ts(eid))); ifexists tcm inset tcm_s & is_TrafficLight(tcm) then trigger(eid) := if eid insetdom trigger then AddTrig(trigger(eid),SetTrafficLight(eid, ts(eid))) else AddTrig({},SetTrafficLight(eid, ts(eid))); ifexists tcm inset tcm_s & is_RampMeter(tcm) then trigger(eid) := if eid insetdom trigger then AddTrig(trigger(eid),SetRampMetering(eid, ts(eid))) else AddTrig({},SetRampMetering(eid, ts(eid))) elseskip) elseskip); forall rid inset myedges do let mk_(d,v,-,-,bridgeopen) = ts(rid) in
(if v < LOWSPEEDTHRESHOLD or d > HIGHDENSITYTHRESHOLD or d = 0 or bridgeopen then problematicedges := problematicedges union {rid};
bridges(rid) := if rid insetdom bridges and bridgeopen then mk_Bridge(<open>) else mk_Bridge(<closed>); forall rid2 inset {beid | beid insetdom bridges & bridges(beid).status = <open>} do let eids = {leid | leid inset leadsto(rid2)
& leid insetdom control and exists tcm inset control(leid) & is_Diversion(tcm)} in forall eid inset eids do
trigger(eid) := if eid insetdom trigger then AddTrig(trigger(eid),SetDiversion(rid2)) else AddTrig({},SetDiversion(rid2)); forall rid2 inset {beid | beid insetdom bridges & bridges(beid).status = <closed>} do let eids = {leid | leid inset leadsto(rid2)
& leid insetdom control and exists tcm inset control(leid) & is_Diversion(tcm)} in forall eid inset eids do
trigger(eid) := if eid insetdom trigger then AddTrig(trigger(eid),SetDiversion(nil)) else AddTrig({},SetDiversion(nil))
); if oldproblematicedges \problematicedges <> {} thenlet non = oldproblematicedges \problematicedges inskip;
IO`printf("Own triggers of %s: %s\n", [myid, trigger]);
IO`printf("Problematic edges of %s: %s\n", [myid, problematicedges]);
IO`printf("No longer Problematic edges of %s\n", [oldproblematicedges\problematicedges]);
)) predom control subsetdom ts;
SetLaneClosure: Network`EdgeId * Environment`EdgeSit ==> setof TCM
SetLaneClosure(eid, mk_(-,-,-,incident,-)) == if incident then (problematicedges := problematicedges union {eid};
incidents := incidents union {eid}; return {mk_LaneClosure(1)}
) elseifnot incident and eid inset incidents then (actctrl := {eid} <-: actctrl;
problematicedges := problematicedges \ {eid};
incidents := incidents\{eid}; return {mk_LaneClosure(0)}
) elsereturn {};
SetHardShoulder: Network`EdgeId * Environment`EdgeSit ==> setof TCM
SetHardShoulder(eid, mk_(d,v,-,-,-)) ==
(IO`printf("Density at %s is %s\n",[eid,d]); if v < LOWSPEEDTHRESHOLD or d > HIGHDENSITYTHRESHOLD then (problematicedges := problematicedges union {eid}; if eid insetdom actctrl => forall tcm inset actctrl(eid) & not is_HardShoulder(tcm) then (actctrl(eid) := {mk_(eid,mk_HardShoulder(true))} union if eid insetdom actctrl then actctrl(eid) else {}; return {mk_HardShoulder(true)}) elsereturn {}
) else (if v >= HIGHSPEEDTHRESHOLD and d <= LOWDENSITYTHRESHOLD --and eid in set dom actctrl then (actctrl := {eid} <-: actctrl;
problematicedges := problematicedges \ {eid}; return {mk_HardShoulder(false)}) elsereturn {}
)
);
SetMaxSpeed: Network`EdgeId * Environment`EdgeSit ==> setof TCM
SetMaxSpeed(eid, mk_(d,-,-,-,-)) == if d > HIGHDENSITYTHRESHOLD then (problematicedges := problematicedges union {eid}; if eid insetdom actctrl => forall tcm inset actctrl(eid) & not is_MaxSpeed(tcm) thenreturn {mk_MaxSpeed(network.GetMaxSpeed(eid)-DELTASPEED)} elsereturn {}
) else (if d <= LOWDENSITYTHRESHOLD -- and eid in set dom actctrl then (actctrl := {eid} <-: actctrl;
problematicedges := problematicedges \ {eid}; return {mk_MaxSpeed(nil)}) elsereturn {}
);
pure SetDiversion: [Network`EdgeId] ==> setof TCM
SetDiversion(eid) == if eid = nil thenreturn {} elsereturn {mk_Diversion("Avoid " ^ eid)};
SetTrafficLight: Network`EdgeId * Environment`EdgeSit ==> setof TCM
SetTrafficLight(eid, mk_(d,-,-,-,-)) == if d > HIGHDENSITYTHRESHOLD then (problematicedges := problematicedges union {eid}; return {mk_TrafficLight(true, LONGGREENTIME)}
) elseif d < LOWDENSITYTHRESHOLD thenreturn {mk_TrafficLight(true, NORMALGREENTIME)} elsereturn {};
SetRampMetering: Network`EdgeId * Environment`EdgeSit ==> setof TCM
SetRampMetering(eid, mk_(d,-,-,-,-)) == if d > HIGHDENSITYTHRESHOLD then (problematicedges := problematicedges union {eid}; return {mk_RampMeter(LONGREDTIME)}
) elseif d < LOWDENSITYTHRESHOLD then (actctrl := {eid} <-: actctrl;
problematicedges := problematicedges \ {eid}; return {mk_RampMeter(NORMALREDTIME)}) elsereturn {};
-- The following operation generates "reguests for help" by an edge with a "problem" -- from adjacent edges. The request for help is expressed in terms of a service required by -- the edge form the adjacent edge. From thte total set of services available this wil only -- be a request for <IncreaseInput> (for output edges) or <DecreaseOutput> (for input edges).
GenerateRequestsForHelp: () ==> map Network`EdgeId tosetof Network`Request
GenerateRequestsForHelp() ==
(dcl requests: map Network`EdgeId tosetof Network`Request := {|->}; forall eid inset problematicedges do ifexists ieid inset interestededges &
{ieid, eid} subsetdom network.GetConnections() and
network.IsOutputEdge (ieid, eid) thenlet ieid inset interestededges best network.IsOutputEdge (ieid, eid) in let severe = Utility(network.GetMaxSpeed(eid),trafsit(eid), prios(eid)),
r = mk_Network`Request (eid, <IncreaseInput>, severe, 0, false) in
requests(ieid) := if ieid insetdom requests then requests(ieid) union {r} else {r} elseifexists ieid inset interestededges &
{ieid, eid} subsetdom network.GetConnections() and
network.IsInputEdge (ieid, eid) thenlet ieid inset interestededges best network.IsInputEdge (ieid, eid) in let severe = Utility(network.GetMaxSpeed(eid),trafsit(eid), prios(eid)),
r = mk_Network`Request (eid, <DecreaseOutput>, severe, 0, false),
rm = {eid2 |-> mk_Network`Request (eid, <DecreaseOutput>, severe, 0, false)
| eid2 inset leadsto(eid)} in
(requests(ieid) := if ieid insetdom requests then requests(ieid) union {r} else {r};
requests := requests ++ {eid3 |-> {rm(eid3)} unionif eid3 insetdom requests then requests(eid3) else {}
| eid3 insetdom rm}) elseskip; return requests
) pre problematicedges subsetdom trafsit and
problematicedges subsetdom prios;
public Step: Environment`TrafficSituation ==> ()
Step(ts) ==
(dcl deltcm : TCM;
IO`printf("Available controls for %s: %s\n", [myid, control]);
trigger:= {|->};
trafsit := ts;
GenerateMyOwnTriggers(ts); let requests = GenerateRequestsForHelp() in
( network.CancelOldProblematicEdges(myid,oldproblematicedges\problematicedges);
IO`printf("Requests: %s\n", [requests]);
network.AddRequests (requests); let noproblems = network.GetNotProblematic() in forall eid inset noproblems do forall acteid insetdom actctrl do iflet pairs = actctrl(acteid) inexists p inset pairs & p.#1 = eid then (deltcm := let p inset actctrl(acteid) best p.#1 = eid in p.#2;
actctrl := {acteid} <-: actctrl;
trigger(acteid) := cases deltcm:
mk_Diversion(-) -> {mk_Diversion(nil)},
mk_HardShoulder(true) -> {mk_HardShoulder(false)}, others -> undefined-- not yet tested end
)
)
);
public MakeOffers: () ==> ()
MakeOffers() ==
(forall eid inset myedges do let requestedservice = network.GetRequests(eid) in if eid insetdom control and requestedservice <> {} and
(eid insetdom actctrl => actctrl(eid) <> {}) -- Don't make an offer if it is in conflict with what is already there then-- here an arbitrary choice is made in case multiple requests are made for an edge. -- In reality this should be improved in the future let requestor inset {ser.originator | ser inset requestedservice} in let severity inset {ser.severity | ser inset requestedservice} in let tcm = RequestedServices2PossibleTCMs(requestor, eid, {e.service | e inset requestedservice}) in let cost = Utility(network.GetMaxSpeed(eid),trafsit(eid), prios(eid))-severity in if tcm <> {} then ( network.MakeOffer (eid, cost);
negos := negos + 1;
IO`printf("Offers made by %s: %s with cost %s\n", [myid, negos, cost])
);
);
public EvaluateOffers: () ==> ()
EvaluateOffers () ==
(forall eid inset myedges do let offers = network.GetOffers(eid) in forall provider insetdom offers do let reqs = offers(provider) in
network.AcceptOffers (provider, {if request.cost < ACCEPTABLECOSTS thenmu(request,accepted |-> true) else request
| request inset reqs})
);
public FinaliseOffers: () ==> Control
FinaliseOffers() ==
(forall eid inset myedges do let offers = network.GetAcceptedOffers(eid),
nonproblem = network.GetNotProblematic() in if eid insetdom control and (offers <> {} or nonproblem <> {}) and true-- To be extended for cases where the requested service is in conflict with what is already there thenif nonproblem <> {} thenforall non inset nonproblem do let tcm = if eid insetdom actctrl then {p.#2 | p inset actctrl(eid) & p.#1 = non} else {},
canceltcm = {cases t:
mk_HardShoulder(-) -> mk_HardShoulder(false),
mk_MaxSpeed(-) -> mk_MaxSpeed(nil),
mk_LaneClosure(-) -> mk_LaneClosure(0),
mk_Diversion(-) -> mk_Diversion(nil),
mk_TrafficLight(-,-) -> mk_TrafficLight(true, NORMALGREENTIME),
mk_RampMeter(-) -> mk_RampMeter(NORMALREDTIME) end
| t inset tcm} in
trigger(eid) := canceltcm union if eid insetdom trigger then trigger(eid) else {} elselet requestor inset { ser.originator | ser inset offers} in let tcm = RequestedServices2PossibleTCMs(requestor, eid, {e.service | e inset offers}) in
(trigger(eid) := tcm union if eid insetdom trigger then trigger(eid) else {}; cases trigger(eid): -- this only works if there is exactly one tcm in the trigger for an edge
{mk_HardShoulder(false)},
{mk_MaxSpeed(nil)},
{mk_LaneClosure(0)},
{mk_TrafficLight(true, (NORMALGREENTIME))},
{mk_Diversion(nil)},
{mk_RampMeter((NORMALREDTIME))} -> actctrl := {eid} <-: actctrl, others -> let tcmpairs = {mk_(requestor,t) | t inset tcm} in
actctrl := actctrl ++ {eid |-> tcmpairs union if eid insetdom actctrl then actctrl(eid) else {}} end);
acceptedoffers := acceptedoffers + 1;
IO`printf("Accepted offers by %s: %s\n", [myid, acceptedoffers]);
IO`printf("Final set of triggers generated by %s: %s\n", [myid, trigger]); return trigger
);
-- This operation needs to determine which traffic control measures can be applied -- in response to a request for help, expressed in terms of a "service" to be -- provided. Multiple service can be requested, and in turn multiple control -- measures can be suggested. So it can be quite complicated, e.g. in cases where -- requested services are contradictory (e.g. IncreaseCapacity, DecreaseCapacity. -- The operation is not so advanced yet, it only deals with one arbitrary control -- measure that can provide the service. Contradictory services are not yet dealt -- with.
pure RequestedServices2PossibleTCMs: Network`EdgeId * Network`EdgeId * setof ServiceId ==> setof TCM
RequestedServices2PossibleTCMs (rid, eid, services) == cases services:
{<IncreaseInput>} -> ifexists tcm inset control(eid) & is_RampMeter(tcm) thenreturn {mk_RampMeter(let redtime = GetCurrentRedTime(eid) in if redtime > STEPREDTIME then redtime - STEPREDTIME else NORMALREDTIME)} elsereturn {},
{<DecreaseOutput>} -> ifexists tcm inset control(eid) & is_Diversion(tcm) thenreturn SetDiversion(rid) -- Diversion needs to be set properly. For this the eid of the requestor for help needs to be included in the game. elsereturn {},
{<IncreaseInput>,
<DecreaseOutput>} -> return {}, -- not sophisticated enough. others -> return {} end;
-- This operation returns the current red time of a RampMeter at the beginning -- of an edge. Obviously it still needs to be done properly.
pure GetCurrentRedTime: Network`EdgeId ==> nat
GetCurrentRedTime (eid) == if eid insetdom actctrl andexists tcm inset actctrl(eid) & is_RampMeter(tcm.#2) thenlet tcm inset actctrl(eid) best is_RampMeter(tcm.#2) inreturn tcm.#2.redtime elsereturn STANDARDREDTIME;
functions
-- The Utility function needs fine tuning
Utility: nat1 * Environment`EdgeSit * Priority +> real
Utility (maxspeed, ts, prio) == let mk_(-,v,-,-,-) = ts in
(maxspeed - v)/ prio pre maxspeed >= ts.#2 and prio <> 0;
DifferentTypes: TCM * TCM +> bool
DifferentTypes(t,s) == not ((is_MaxSpeed(t) and is_MaxSpeed(s)) or
(is_Diversion(t) and is_Diversion(s)) or
(is_TrafficLight(t) and is_TrafficLight(s)) or
(is_RampMeter(t) and is_RampMeter(s)) or
(is_HardShoulder(t) and is_HardShoulder(s)) or
(is_LaneClosure(t) and is_LaneClosure(s)));
end TMS
¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.21Angebot
Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.