From: Mikko Rasa Date: Sun, 10 Oct 2010 09:21:07 +0000 (+0000) Subject: Support taking trains off the tracks X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=1f9af43b6ab300693c044b431e95b25422b36507;p=r2c2.git Support taking trains off the tracks Don't give up a block that still has vehicles on it Fix get_reserved_distance after placing a long train Don't use speed steps more than 3 above the last known one --- diff --git a/source/libmarklin/train.cpp b/source/libmarklin/train.cpp index acf8aa5..d6ed044 100644 --- a/source/libmarklin/train.cpp +++ b/source/libmarklin/train.cpp @@ -288,15 +288,32 @@ void Train::place(Block &block, unsigned entry) const Block::Endpoint &bep = block.get_endpoints()[exit]; Track *track = bep.track->get_link(bep.track_ep); unsigned ep = track->get_endpoint_by_link(*bep.track); - vehicles.front()->place(track, ep, 0, Vehicle::FRONT_BUFFER); + vehicles.front()->place(*track, ep, 0, Vehicle::FRONT_BUFFER); } else { const Block::Endpoint &bep = block.get_endpoints()[entry]; - vehicles.back()->place(bep.track, bep.track_ep, 0, Vehicle::BACK_BUFFER); + vehicles.back()->place(*bep.track, bep.track_ep, 0, Vehicle::BACK_BUFFER); } } +void Train::unplace() +{ + if(controller->get_speed()) + throw InvalidState("Must be stopped before unplacing"); + + release_blocks(rsv_blocks); + release_blocks(cur_blocks); + + set_active(false); + accurate_position = false; + + for(vector::iterator i=vehicles.begin(); i!=vehicles.end(); ++i) + (*i)->unplace(); + + set_status("Unplaced"); +} + bool Train::free_block(Block &block) { float margin = 10*layout.get_catalogue().get_scale(); @@ -547,10 +564,10 @@ void Train::sensor_event(unsigned addr, bool state) { Track *track = bep.track->get_link(bep.track_ep); unsigned ep = track->get_endpoint_by_link(*bep.track); - vehicles.back()->place(track, ep, 0, Vehicle::BACK_AXLE); + vehicles.back()->place(*track, ep, 0, Vehicle::BACK_AXLE); } else - vehicles.front()->place(bep.track, bep.track_ep, 0, Vehicle::FRONT_AXLE); + vehicles.front()->place(*bep.track, bep.track_ep, 0, Vehicle::FRONT_AXLE); } } last_entry_time = Time::now(); @@ -585,9 +602,14 @@ void Train::sensor_event(unsigned addr, bool state) } else { + const Vehicle &veh = *(reverse ? vehicles.front() : vehicles.back()); + // Find the first sensor in our current blocks that's still active list::iterator end = cur_blocks.begin(); for(list::iterator i=cur_blocks.begin(); i!=cur_blocks.end(); ++i) + { + if(i->block->get_tracks().count(veh.get_track())) + break; if(i->block->get_sensor_id()) { if(layout.get_driver().get_sensor(i->block->get_sensor_id())) @@ -598,6 +620,7 @@ void Train::sensor_event(unsigned addr, bool state) ++end; } } + } if(end!=cur_blocks.begin() && end!=cur_blocks.end()) // Free blocks up to the last inactive sensor @@ -891,9 +914,17 @@ float Train::get_reserved_distance_until(const Block *until_block, bool back) co return 0; list::const_iterator block = cur_blocks.begin(); - while(block!=cur_blocks.end() && !block->block->get_tracks().count(track)) + while(block!=rsv_blocks.end() && !block->block->get_tracks().count(track)) + { ++block; - if(block==cur_blocks.end() || block->block==until_block) + if(block==cur_blocks.end()) + { + if(back) + return 0; + block = rsv_blocks.begin(); + } + } + if(block==rsv_blocks.end() || block->block==until_block) return 0; unsigned entry = veh.get_entry(); @@ -979,9 +1010,11 @@ unsigned Train::find_speed(float real) const unsigned low = 0; unsigned high = 0; + unsigned last = 0; for(unsigned i=0; (!high && i<=14); ++i) if(real_speed[i].weight) { + last = i; if(real_speed[i].speed(low*real/real_speed[low].speed), 14U); + return min(min(static_cast(low*real/real_speed[low].speed), 14U), last+3); } float f = (real-real_speed[low].speed)/(real_speed[high].speed-real_speed[low].speed); @@ -1091,7 +1124,7 @@ void Train::Loader::finish() { const BlockRef &blkref = obj.cur_blocks.front(); const Block::Endpoint &bep = blkref.block->get_endpoints()[blkref.entry]; - obj.vehicles.back()->place(bep.track, bep.track_ep, 0, Vehicle::BACK_BUFFER); + obj.vehicles.back()->place(*bep.track, bep.track_ep, 0, Vehicle::BACK_BUFFER); obj.set_status("Stopped"); } diff --git a/source/libmarklin/train.h b/source/libmarklin/train.h index f00d0fc..02d1d52 100644 --- a/source/libmarklin/train.h +++ b/source/libmarklin/train.h @@ -137,6 +137,7 @@ public: void go_to(const Track &); const Route *get_route() const { return route; } void place(Block &, unsigned); + void unplace(); bool is_placed() const { return !cur_blocks.empty(); } bool free_block(Block &); int get_entry_to_block(Block &) const; diff --git a/source/libmarklin/vehicle.cpp b/source/libmarklin/vehicle.cpp index 75afa4b..5a26f92 100644 --- a/source/libmarklin/vehicle.cpp +++ b/source/libmarklin/vehicle.cpp @@ -83,9 +83,9 @@ void Vehicle::detach_front() prev = 0; } -void Vehicle::place(Track *t, unsigned e, float o, PlaceMode m) +void Vehicle::place(Track &t, unsigned e, float o, PlaceMode m) { - track_pos = TrackPosition(t, e, o); + track_pos = TrackPosition(&t, e, o); if(m==FRONT_AXLE) track_pos.advance(-type.get_front_axle_offset()); @@ -100,6 +100,19 @@ void Vehicle::place(Track *t, unsigned e, float o, PlaceMode m) propagate_position(); } +void Vehicle::unplace() +{ + if(!track_pos.track) + return; + + track_pos = TrackPosition(); + + if(prev) + prev->unplace(); + if(next) + next->unplace(); +} + void Vehicle::advance(float d) { track_pos.advance(d); diff --git a/source/libmarklin/vehicle.h b/source/libmarklin/vehicle.h index efd4534..75ae859 100644 --- a/source/libmarklin/vehicle.h +++ b/source/libmarklin/vehicle.h @@ -65,7 +65,8 @@ public: Vehicle *get_next() const { return next; } Vehicle *get_previous() const { return prev; } - void place(Track *, unsigned, float, PlaceMode = CENTER); + void place(Track &, unsigned, float, PlaceMode = CENTER); + void unplace(); void advance(float); Track *get_track() const { return track_pos.track; } unsigned get_entry() const { return track_pos.ep; }