]> git.tdb.fi Git - r2c2.git/commitdiff
Support taking trains off the tracks
authorMikko Rasa <tdb@tdb.fi>
Sun, 10 Oct 2010 09:21:07 +0000 (09:21 +0000)
committerMikko Rasa <tdb@tdb.fi>
Sun, 10 Oct 2010 09:21:07 +0000 (09:21 +0000)
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

source/libmarklin/train.cpp
source/libmarklin/train.h
source/libmarklin/vehicle.cpp
source/libmarklin/vehicle.h

index acf8aa51486de42adb8901b98f9c78f2d0b79ac0..d6ed044954286ba549c0da0c0e75d363e300861e 100644 (file)
@@ -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<Vehicle *>::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<BlockRef>::iterator end = cur_blocks.begin();
                for(list<BlockRef>::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<BlockRef>::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<real)
                                low = i;
                        else
@@ -996,7 +1029,7 @@ unsigned Train::find_speed(float real) const
                        else
                                return 0;
                }
-               return min(static_cast<unsigned>(low*real/real_speed[low].speed), 14U);
+               return min(min(static_cast<unsigned>(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");
        }
index f00d0fceec719d37b51242bddb6671394ab1c407..02d1d52de1b8751d411bc5aa063300f46d2fb110 100644 (file)
@@ -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;
index 75afa4bba78f9c10c03c4fb3254875d49770d9d1..5a26f9294b665c8a5178696e482f78a8489f17dd 100644 (file)
@@ -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);
index efd4534899f24ed80a3e922385016b335bda062b..75ae85954c4ef1e4b2f5fb128873c41aa767140c 100644 (file)
@@ -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; }