]> git.tdb.fi Git - r2c2.git/commitdiff
Make vehicles trigger sensors as they pass over them, allowing full simulation
authorMikko Rasa <tdb@tdb.fi>
Tue, 28 Sep 2010 14:03:45 +0000 (14:03 +0000)
committerMikko Rasa <tdb@tdb.fi>
Tue, 28 Sep 2010 14:03:45 +0000 (14:03 +0000)
source/libmarklin/vehicle.cpp
source/libmarklin/vehicle.h
source/libmarklin/vehicletype.cpp
source/libmarklin/vehicletype.h

index 109c3f420d91621a44f427b70fae241669dfce71..d81848076c5984a26928873a49b13023785817d1 100644 (file)
@@ -7,6 +7,7 @@ Distributed under the GPL
 
 #include <cmath>
 #include "catalogue.h"
+#include "driver.h"
 #include "layout.h"
 #include "track.h"
 #include "tracktype.h"
@@ -24,7 +25,9 @@ Vehicle::Vehicle(Layout &l, const VehicleType &t):
        next(0),
        prev(0),
        direction(0),
-       bogie_dirs(type.get_bogies().size())
+       bogie_dirs(type.get_bogies().size()),
+       front_sensor(0),
+       back_sensor(0)
 {
        layout.add_vehicle(*this);
 }
@@ -79,31 +82,11 @@ void Vehicle::place(Track *t, unsigned e, float o, PlaceMode m)
        track_pos = TrackPosition(t, e, o);
 
        if(m==FRONT_AXLE)
-       {
-               float front = type.get_length()/2;
-               if(!type.get_axles().empty())
-                       front = type.get_axles().front().position;
-               if(!type.get_bogies().empty())
-               {
-                       const VehicleType::Bogie &bogie = type.get_bogies().front();
-                       front = max(front, bogie.position+bogie.axles.front().position);
-               }
-               track_pos.advance(-front);
-       }
+               track_pos.advance(-type.get_front_axle_offset());
        else if(m==FRONT_BUFFER)
                track_pos.advance(-type.get_length()/2);
        else if(m==BACK_AXLE)
-       {
-               float back = type.get_length()/2;
-               if(!type.get_axles().empty())
-                       back = type.get_axles().back().position;
-               if(!type.get_bogies().empty())
-               {
-                       const VehicleType::Bogie &bogie = type.get_bogies().back();
-                       back = min(back, bogie.position+bogie.axles.back().position);
-               }
-               track_pos.advance(-back);
-       }
+               track_pos.advance(-type.get_back_axle_offset());
        else if(m==BACK_BUFFER)
                track_pos.advance(type.get_length()/2);
 
@@ -130,39 +113,41 @@ void Vehicle::update_position()
        TrackPoint tp;
 
        const vector<VehicleType::Axle> &axles = type.get_axles();
+       const vector<VehicleType::Bogie> &bogies = type.get_bogies();
        if(axles.size()>=2)
        {
                float wheelbase = axles.front().position-axles.back().position;
                tp = get_point(track_pos, wheelbase, -axles.back().position/wheelbase);
        }
-       else
+       else if(bogies.size()>=2)
        {
-               const vector<VehicleType::Bogie> &bogies = type.get_bogies();
-               if(bogies.size()>=2)
-               {
-                       TrackPosition front = track_pos;
-                       front.advance(bogies.front().position);
-                       TrackPosition back = track_pos;
-                       back.advance(bogies.back().position);
-                       float bogie_spacing = bogies.front().position-bogies.back().position;
-                       adjust_for_distance(front, back, bogie_spacing);
+               TrackPosition front = track_pos;
+               front.advance(bogies.front().position);
+               TrackPosition back = track_pos;
+               back.advance(bogies.back().position);
+               float bogie_spacing = bogies.front().position-bogies.back().position;
+               adjust_for_distance(front, back, bogie_spacing);
 
-                       const vector<VehicleType::Axle> &front_axles = bogies.front().axles;
-                       float wheelbase = front_axles.front().position-front_axles.back().position;
-                       TrackPoint front_point = get_point(front, wheelbase, -front_axles.back().position/wheelbase);
+               const vector<VehicleType::Axle> &front_axles = bogies.front().axles;
+               float wheelbase = front_axles.front().position-front_axles.back().position;
+               TrackPoint front_point = get_point(front, wheelbase, -front_axles.back().position/wheelbase);
 
-                       const vector<VehicleType::Axle> &back_axles = bogies.back().axles;
-                       wheelbase = back_axles.front().position-back_axles.back().position;
-                       TrackPoint back_point = get_point(back, wheelbase, -back_axles.back().position/wheelbase);
+               const vector<VehicleType::Axle> &back_axles = bogies.back().axles;
+               wheelbase = back_axles.front().position-back_axles.back().position;
+               TrackPoint back_point = get_point(back, wheelbase, -back_axles.back().position/wheelbase);
 
-                       tp = get_point(front_point.pos, back_point.pos, -bogies.back().position/bogie_spacing);
+               tp = get_point(front_point.pos, back_point.pos, -bogies.back().position/bogie_spacing);
 
-                       bogie_dirs.front() = front_point.dir-tp.dir;
-                       bogie_dirs.back() = back_point.dir-tp.dir;
-               }
-               else
-                       tp = track_pos.get_point();
+               bogie_dirs.front() = front_point.dir-tp.dir;
+               bogie_dirs.back() = back_point.dir-tp.dir;
        }
+       else
+               tp = track_pos.get_point();
+
+       if(!prev)
+               check_sensor(type.get_front_axle_offset(), front_sensor);
+       if(!next)
+               check_sensor(type.get_back_axle_offset(), back_sensor);
 
        position = tp.pos;
        direction = tp.dir;
@@ -213,6 +198,31 @@ void Vehicle::propagate_backward()
                next->propagate_backward();
 }
 
+void Vehicle::check_sensor(float offset, unsigned &sensor)
+{
+       TrackPosition pos = track_pos;
+       pos.advance(offset);
+       unsigned s = pos.track->get_sensor_id();
+       if(s!=sensor)
+       {
+               /* Sensor ID under axle has changed.  Deduce movement direction by using
+               the sensor ID under the midpoint of the vehicle. */
+               unsigned old = sensor;
+               sensor = s;
+               unsigned mid = track_pos.track->get_sensor_id();
+
+               if(s && s!=mid)
+                       /* There's a sensor and it's different from mid.  We've just entered
+                       that sensor. */
+                       // XXX The Train will reset the vehicles to the start of the sensor, which is somewhat undesirable
+                       layout.get_driver().set_sensor(sensor, true);
+               if(old && old!=mid)
+                       /* A sensor was under the axle and it was different from mid.  We've
+                       just left that sensor. */
+                       layout.get_driver().set_sensor(old, false);
+       }
+}
+
 void Vehicle::adjust_for_distance(TrackPosition &front, TrackPosition &back, float tdist, float ratio) const
 {
        float margin = 0.01*layout.get_catalogue().get_scale();
index 303c6686a339d6fc938823f6e80ac2d0426b373b..efd4534899f24ed80a3e922385016b335bda062b 100644 (file)
@@ -49,6 +49,8 @@ private:
        Point position;
        float direction;
        std::vector<float> bogie_dirs;
+       unsigned front_sensor;
+       unsigned back_sensor;
 
 public:
        Vehicle(Layout &, const VehicleType &);
@@ -77,6 +79,7 @@ private:
        void propagate_position();
        void propagate_forward();
        void propagate_backward();
+       void check_sensor(float, unsigned &);
 
        void adjust_for_distance(TrackPosition &, TrackPosition &, float, float = 0.5) const;
        TrackPoint get_point(const Point &, const Point &, float = 0.5) const;
index dd15b48f964794b2291775f98fae9cb6dadc8d44..937ce89cf28050601a0e19ef6c7fdd66186ff90d 100644 (file)
@@ -26,6 +26,32 @@ unsigned VehicleType::get_max_function() const
        return (--functions.end())->first;
 }
 
+float VehicleType::get_front_axle_offset() const
+{
+       float front = length/2;
+       if(!axles.empty())
+               front = axles.front().position;
+       if(!bogies.empty())
+       {
+               const Bogie &bogie = bogies.front();
+               front = max(front, bogie.position+bogie.axles.front().position);
+       }
+       return front;
+}
+
+float VehicleType::get_back_axle_offset() const
+{
+       float back = -length/2;
+       if(!axles.empty())
+               back = axles.back().position;
+       if(!bogies.empty())
+       {
+               const Bogie &bogie = bogies.back();
+               back = min(back, bogie.position+bogie.axles.back().position);
+       }
+       return back;
+}
+
 
 VehicleType::Axle::Axle():
        position(0),
index 2edf3bf55fee5242a11c73cb363327fcd70f4f61..082e3bc1e2167e3a66a0e10147b677b94028e210 100644 (file)
@@ -90,6 +90,8 @@ public:
        float get_height() const { return height; }
        const std::vector<Axle> &get_axles() const { return axles; }
        const std::vector<Bogie> &get_bogies() const { return bogies; }
+       float get_front_axle_offset() const;
+       float get_back_axle_offset() const;
        const std::string &get_object() const { return object; }
 };