Realistic braking: Cache offset of centre of mass of train

pull/238/head
Jonathan G Rennison 3 years ago
parent 7ae5e5b89f
commit 26a123b708

@ -102,16 +102,25 @@ void GroundVehicle<T, Type>::CargoChanged()
{
assert(this->First() == this);
uint32 weight = 0;
uint64 mass_offset = 0;
uint32 veh_offset = 0;
for (T *u = T::From(this); u != nullptr; u = u->Next()) {
uint32 current_weight = u->GetWeight();
if (Type == VEH_TRAIN) Train::From(u)->tcache.cached_veh_weight = current_weight;
if (Type == VEH_TRAIN) {
Train::From(u)->tcache.cached_veh_weight = current_weight;
mass_offset += current_weight * (veh_offset + (Train::From(u)->gcache.cached_veh_length / 2));
veh_offset += Train::From(u)->gcache.cached_veh_length;
}
weight += current_weight;
/* Slope steepness is in percent, result in N. */
u->gcache.cached_slope_resistance = current_weight * u->GetSlopeSteepness() * 100;
u->InvalidateImageCache();
}
ClrBit(this->vcache.cached_veh_flags, VCF_GV_ZERO_SLOPE_RESIST);
if (Type == VEH_TRAIN) {
Train::From(this)->tcache.cached_centre_mass = (weight != 0) ? (mass_offset / weight) : (this->gcache.cached_total_length / 2);
}
/* Store consist weight in cache. */
this->gcache.cached_weight = std::max(1u, weight);

@ -1646,10 +1646,11 @@ void CheckCaches(bool force_check, std::function<void(const char *)> log)
print_gv_cache_diff("train", gro_cache[length], Train::From(u)->gcache);
}
if (memcmp(&tra_cache[length], &Train::From(u)->tcache, sizeof(TrainCache)) != 0) {
CCLOGV("train cache mismatch: %c%c%c%c%c%c%c%c",
CCLOGV("train cache mismatch: %c%c%c%c%c%c%c%c%c",
tra_cache[length].cached_override != Train::From(u)->tcache.cached_override ? 'o' : '-',
tra_cache[length].cached_tilt != Train::From(u)->tcache.cached_tilt ? 't' : '-',
tra_cache[length].cached_num_engines != Train::From(u)->tcache.cached_num_engines ? 'e' : '-',
tra_cache[length].cached_centre_mass != Train::From(u)->tcache.cached_centre_mass ? 'm' : '-',
tra_cache[length].cached_veh_weight != Train::From(u)->tcache.cached_veh_weight ? 'w' : '-',
tra_cache[length].cached_uncapped_decel != Train::From(u)->tcache.cached_uncapped_decel ? 'D' : '-',
tra_cache[length].cached_deceleration != Train::From(u)->tcache.cached_deceleration ? 'd' : '-',

@ -1148,6 +1148,7 @@ struct train_venc {
GroundVehicleCache gvcache;
bool cached_tilt;
uint8 cached_num_engines;
uint16 cached_centre_mass;
uint16 cached_veh_weight;
uint16 cached_uncapped_decel;
uint8 cached_deceleration;
@ -1215,6 +1216,7 @@ void Save_VENC()
write_gv_cache(t->gcache);
SlWriteByte(t->tcache.cached_tilt);
SlWriteByte(t->tcache.cached_num_engines);
SlWriteByte(t->tcache.cached_centre_mass);
SlWriteUint16(t->tcache.cached_veh_weight);
SlWriteUint16(t->tcache.cached_uncapped_decel);
SlWriteByte(t->tcache.cached_deceleration);
@ -1275,6 +1277,7 @@ void Load_VENC()
read_gv_cache(venc.gvcache);
venc.cached_tilt = SlReadByte();
venc.cached_num_engines = SlReadByte();
venc.cached_centre_mass = SlReadUint16();
venc.cached_veh_weight = SlReadUint16();
venc.cached_uncapped_decel = SlReadUint16();
venc.cached_deceleration = SlReadByte();
@ -1361,6 +1364,7 @@ void SlProcessVENC()
check_gv_cache(t->gcache, venc.gvcache, t);
CheckVehicleVENCProp(t->tcache.cached_tilt, venc.cached_tilt, t, "cached_tilt");
CheckVehicleVENCProp(t->tcache.cached_num_engines, venc.cached_num_engines, t, "cached_num_engines");
CheckVehicleVENCProp(t->tcache.cached_centre_mass, venc.cached_centre_mass, t, "cached_centre_mass");
CheckVehicleVENCProp(t->tcache.cached_veh_weight, venc.cached_veh_weight, t, "cached_veh_weight");
CheckVehicleVENCProp(t->tcache.cached_uncapped_decel, venc.cached_uncapped_decel, t, "cached_uncapped_decel");
CheckVehicleVENCProp(t->tcache.cached_deceleration, venc.cached_deceleration, t, "cached_deceleration");

@ -151,8 +151,8 @@ class NIHVehicle : public NIHelper {
}
if (v->type == VEH_TRAIN) {
const Train *t = Train::From(v);
seprintf(buffer, lastof(buffer), " T cache: tilt: %u, engines: %u, decel: %u, uncapped decel: %u",
t->tcache.cached_tilt, t->tcache.cached_num_engines, t->tcache.cached_deceleration, t->tcache.cached_uncapped_decel);
seprintf(buffer, lastof(buffer), " T cache: tilt: %u, engines: %u, decel: %u, uncapped decel: %u, centre mass: %u",
t->tcache.cached_tilt, t->tcache.cached_num_engines, t->tcache.cached_deceleration, t->tcache.cached_uncapped_decel, t->tcache.cached_centre_mass);
print(buffer);
seprintf(buffer, lastof(buffer), " T cache: veh weight: %u, user data: %u, curve speed: %u",
t->tcache.cached_veh_weight, t->tcache.user_def_data, t->tcache.cached_max_curve_speed);

@ -99,6 +99,7 @@ struct TrainCache {
/* cached values, recalculated on load and each time a vehicle is added to/removed from the consist. */
bool cached_tilt; ///< train can tilt; feature provides a bonus in curves
uint8 cached_num_engines; ///< total number of engines, including rear ends of multiheaded engines
uint16 cached_centre_mass; ///< Cached position of the centre of mass, from the front
uint16 cached_veh_weight; ///< Cached individual vehicle weight
uint16 cached_uncapped_decel; ///< Uncapped cached deceleration for realistic braking lookahead purposes
uint8 cached_deceleration; ///< Cached deceleration for realistic braking lookahead purposes

@ -364,6 +364,7 @@ void Train::ConsistChanged(ConsistChangeFlags allowed_changes)
u->gcache.cached_air_drag = 0;
u->gcache.cached_total_length = 0;
u->tcache.cached_num_engines = 0;
u->tcache.cached_centre_mass = 0;
u->tcache.cached_deceleration = 0;
u->tcache.cached_uncapped_decel = 0;
u->tcache.cached_tilt = false;
@ -847,8 +848,11 @@ static void LimitSpeedFromLookAhead(int &max_speed, const TrainDecelerationStats
if (distance + current_position > position) {
/* Speed is too fast, we would overshoot */
if (z_delta < 0 && (position - current_position) < stats.t->gcache.cached_total_length) {
/* Reduce z delta near target to compensate for target z not taking into account that z varies across the whole train */
z_delta = (z_delta * (position - current_position)) / stats.t->gcache.cached_total_length;
int effective_length = std::min<int>(stats.t->gcache.cached_total_length, stats.t->tcache.cached_centre_mass * 2);
if ((position - current_position) < effective_length) {
/* Reduce z delta near target to compensate for target z not taking into account that z varies across the whole train */
z_delta = (z_delta * (position - current_position)) / effective_length;
}
}
max_speed = std::min(max_speed, GetRealisticBrakingSpeedForDistance(stats, position - current_position, end_speed, z_delta));
}

Loading…
Cancel
Save