From 5c1ddd2f213af3fea15237e02f7da112c0abba36 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Mon, 3 Jun 2013 22:27:22 +0300 Subject: [PATCH] Tighten safety measures Remove opportunistic freeing of blocks from behind the train and counting of noncritical blocks from the simulated vehicle position. Both features are now implemented in terms of what can be ascertained from sensors. I'm developing infrared gates which will provide similar functionality with actual physical (or simulated) feedback. --- source/libr2c2/blockallocator.cpp | 11 --- source/libr2c2/blockallocator.h | 1 - source/libr2c2/train.cpp | 123 ++++++++---------------------- source/libr2c2/train.h | 2 +- 4 files changed, 32 insertions(+), 105 deletions(-) diff --git a/source/libr2c2/blockallocator.cpp b/source/libr2c2/blockallocator.cpp index 55f932e..fc414cc 100644 --- a/source/libr2c2/blockallocator.cpp +++ b/source/libr2c2/blockallocator.cpp @@ -227,17 +227,6 @@ bool BlockAllocator::reserve_block(const BlockIter &block) } } -void BlockAllocator::release_until(const Block &block) -{ - for(BlockList::iterator i=blocks.begin(); i!=cur_blocks_end; ++i) - if(i->block()==&block) - { - if(++i!=cur_blocks_end) - release_blocks_begin(i); - return; - } -} - bool BlockAllocator::release_from(const Block &block) { bool have_sensor = false; diff --git a/source/libr2c2/blockallocator.h b/source/libr2c2/blockallocator.h index c90b450..39a327b 100644 --- a/source/libr2c2/blockallocator.h +++ b/source/libr2c2/blockallocator.h @@ -60,7 +60,6 @@ public: private: bool reserve_block(const BlockIter &); public: - void release_until(const Block &); bool release_from(const Block &); void release_noncurrent(); private: diff --git a/source/libr2c2/train.cpp b/source/libr2c2/train.cpp index b7dc247..91387d8 100644 --- a/source/libr2c2/train.cpp +++ b/source/libr2c2/train.cpp @@ -232,7 +232,7 @@ void Train::stop_at(Block *block) bool Train::free_block(Block &block) { - if(get_reserved_distance_until(&block, false)get_braking_distance()*1.3) + if(get_reserved_distance_until(&block)get_braking_distance()*1.3) return false; return allocator.release_from(block); @@ -252,53 +252,21 @@ void Train::free_noncritical_blocks() float margin = 10*layout.get_catalogue().get_scale(); float min_dist = controller->get_braking_distance()*1.3+margin; - Vehicle &veh = *(reverse ? vehicles.back() : vehicles.front()); - - TrackIter track = veh.get_track_iter(); - BlockIter block = allocator.first(); - const BlockIter &last_cur = allocator.last_current(); - const BlockIter &last = allocator.last(); - bool in_rsv = false; - while(!block->has_track(*track)) - { - if(&*block==&*last_cur) - in_rsv = true; - if(&*block==&*last) - break; - block = block.next(); - } - - float dist = veh.get_offset(); - if(reverse) - track.reverse(); - else - dist = track->get_type().get_path_length(track->get_active_path())-dist; - dist -= veh.get_type().get_length()/2; - - bool nsens = 0; - while(1) + BlockIter i = allocator.last_current().next(); + float dist = 0; + bool sensor_seen = false; + for(; i->get_train()==this; i=i.next()) { - track = track.next(); - - if(!block->has_track(*track)) + if(dist>min_dist && sensor_seen) { - if(&*block==&*last_cur) - in_rsv = true; - if(&*block==&*last) - return; - block = block.next(); - - if(dist>min_dist && nsens>0) - { - allocator.release_from(*block); - return; - } - - if(in_rsv && block->get_sensor_id()) - ++nsens; + allocator.release_from(*i); + return; } - dist += track->get_type().get_path_length(track->get_active_path()); + dist += i->get_path_length(i.entry()); + + if(i->get_sensor_id()) + sensor_seen = true; } } @@ -312,7 +280,7 @@ float Train::get_reserved_distance() const if(next && next->get_type().is_turnout()) margin = 15*layout.get_catalogue().get_scale(); - return max(get_reserved_distance_until(0, false)-margin, 0.0f); + return max(get_reserved_distance_until(0)-margin, 0.0f); } void Train::reserve_more() @@ -386,14 +354,6 @@ void Train::tick(const Time::TimeStamp &t, const Time::TimeDelta &dt) } } } - - if(!allocator.empty() && !allocator.first()->get_sensor_id()) - { - float dist = get_reserved_distance_until(&*allocator.first(), true); - - if(dist>10*layout.get_catalogue().get_scale()) - allocator.release_until(*allocator.first()); - } } void Train::save(list &st) const @@ -521,65 +481,44 @@ void Train::halt_event(bool h) accurate_position = false; } -float Train::get_reserved_distance_until(const Block *until_block, bool back) const +float Train::get_reserved_distance_until(const Block *until_block) const { if(allocator.empty()) return 0; - Vehicle &veh = *(reverse!=back ? vehicles.back() : vehicles.front()); - const VehicleType &vtype = veh.get_type(); + Vehicle &veh = *(reverse ? vehicles.back() : vehicles.front()); TrackIter track = veh.get_track_iter(); if(!track) // XXX Probably unnecessary return 0; - const BlockIter &first = allocator.first(); - const BlockIter &last = allocator.last(); - BlockIter block = first; - while(!block->has_track(*track)) - { - if(&*block==&*last) - return 0; - block = block.next(); - } + BlockIter block = track.block_iter(); if(&*block==until_block) return 0; - if(back) - block = block.reverse(); - + // Account for the vehicle's offset on its current track float result = veh.get_offset(); - if(reverse!=back) + if(reverse) track = track.reverse(); else result = track->get_type().get_path_length(track->get_active_path())-result; - result -= vtype.get_length()/2; + result -= veh.get_type().get_length()/2; - while(1) - { - track = track.next(); - if(!track) - break; + // Count remaining distance in the vehicle's current block + for(track=track.next(); &track->get_block()==&*block; track=track.next()) + result += track->get_type().get_path_length(track->get_active_path()); - if(!block->has_track(*track)) - { - if(back) - { - if(&*block==&*first) - break; - } - else - { - if(&*block==&*last) - break; - } - block = block.next(); + const BlockIter &last = allocator.last(); + if(&*block==&*last) + return result; - if(&*block==until_block) - break; - } + // Count any remaining blocks + for(block=block.next(); (&*block!=until_block && block->get_train()==this); block=block.next()) + { + result += block->get_path_length(block.entry()); - result += track->get_type().get_path_length(track->get_active_path()); + if(&*block==&*last) + break; } return result; diff --git a/source/libr2c2/train.h b/source/libr2c2/train.h index 03b8b66..42bbc37 100644 --- a/source/libr2c2/train.h +++ b/source/libr2c2/train.h @@ -133,7 +133,7 @@ private: void block_state_changed(Block &, Block::State); void halt_event(bool); void block_reserved(const Block &, const Train *); - float get_reserved_distance_until(const Block *, bool) const; + float get_reserved_distance_until(const Block *) const; }; } // namespace R2C2 -- 2.43.0