From d01230572abde870055844b6efaa777a2ba93226 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Tue, 28 Sep 2010 14:03:45 +0000 Subject: [PATCH] Make vehicles trigger sensors as they pass over them, allowing full simulation --- source/libmarklin/vehicle.cpp | 100 ++++++++++++++++-------------- source/libmarklin/vehicle.h | 3 + source/libmarklin/vehicletype.cpp | 26 ++++++++ source/libmarklin/vehicletype.h | 2 + 4 files changed, 86 insertions(+), 45 deletions(-) diff --git a/source/libmarklin/vehicle.cpp b/source/libmarklin/vehicle.cpp index 109c3f4..d818480 100644 --- a/source/libmarklin/vehicle.cpp +++ b/source/libmarklin/vehicle.cpp @@ -7,6 +7,7 @@ Distributed under the GPL #include #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 &axles = type.get_axles(); + const vector &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 &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 &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 &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 &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 &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(); diff --git a/source/libmarklin/vehicle.h b/source/libmarklin/vehicle.h index 303c668..efd4534 100644 --- a/source/libmarklin/vehicle.h +++ b/source/libmarklin/vehicle.h @@ -49,6 +49,8 @@ private: Point position; float direction; std::vector 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; diff --git a/source/libmarklin/vehicletype.cpp b/source/libmarklin/vehicletype.cpp index dd15b48..937ce89 100644 --- a/source/libmarklin/vehicletype.cpp +++ b/source/libmarklin/vehicletype.cpp @@ -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), diff --git a/source/libmarklin/vehicletype.h b/source/libmarklin/vehicletype.h index 2edf3bf..082e3bc 100644 --- a/source/libmarklin/vehicletype.h +++ b/source/libmarklin/vehicletype.h @@ -90,6 +90,8 @@ public: float get_height() const { return height; } const std::vector &get_axles() const { return axles; } const std::vector &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; } }; -- 2.45.2