#include <cmath>
#include "catalogue.h"
+#include "driver.h"
#include "layout.h"
#include "track.h"
#include "tracktype.h"
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);
}
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);
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;
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();