BT410 5.3.109: the watchers watch -- the heat mirror and the voltage watchdog run per-frame
Two of the 22 stubs killed bottom-up, because the gyro chain needs them: GyroscopeSimulation -> PowerWatcher::Simulation -> UpdateWatch -> HeatWatcher::WatchSimulation. HeatWatcher::WatchSimulation (@004aeac4): resolve the watched subsystem, read its temperature, drive the 3-level heat alarm (Normal / Degradation / Failure). The binary dereferences the watch link unconditionally -- it always binds on a master node; the null guard covers replicants, holding Normal. PowerWatcher::UpdateWatch (@004b181c's body): the heat mirror first, then the watchdog MIRRORS the watched subsystem's electrical state -- which is what drives the Torso's twist-rate power gate and the searchlight/thermal voltage reads -- with one override: a subsystem reading Ready off a SAGGING source (measured <= minVoltage x rated) shows level 1, the BROWNOUT. Both Performances now REGISTER in their ctors on the master instance (the established sibling gate; the binary's form is the segment-copy/master flag pair). They had never been registered before -- which is why the old Fail() stubs never tripped in months of runs: the watchers existed but nothing ever asked them to watch. Plumbing: class-typed Performance shims on both watchers (the base takes the Subsystem-typed pointer -- same shim every sibling carries), HeatableSubsystem::CurrentTemperatureOf() accessor, UpdateWatch declared. Live run clean. Stub census: 20 across 14 files. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -761,9 +761,15 @@ HeatWatcher::HeatWatcher(
|
||||
watchedSubsystem = subsystem_resource->watchedSubsystem;
|
||||
|
||||
//
|
||||
// The master instance runs WatchSimulation per-frame; the install is
|
||||
// deferred with that (staged) method.
|
||||
// Install the per-frame watch on the master instance (the binary gates on
|
||||
// the segment-copy mask + the master flag; our tree's established
|
||||
// equivalent is the replicant test every sibling ctor uses).
|
||||
//
|
||||
if (owner->GetInstance() != Entity::ReplicantInstance)
|
||||
{
|
||||
SetPerformance(&HeatWatcher::WatchSimulation);
|
||||
}
|
||||
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
@@ -804,13 +810,39 @@ void
|
||||
}
|
||||
|
||||
//
|
||||
// Per-frame: resolve the watched subsystem, read its temperature, drive the
|
||||
// 3-level alarm. Not yet reconstructed.
|
||||
// @004aeac4 -- the registered Performance: resolve the watched subsystem,
|
||||
// read its temperature, drive the 3-level alarm. The binary dereferences
|
||||
// the watched link unconditionally (it always binds on a master node); the
|
||||
// null guard covers replicants and bring-up, holding NormalHeat.
|
||||
//
|
||||
void
|
||||
HeatWatcher::WatchSimulation(Scalar)
|
||||
HeatWatcher::WatchSimulation(Scalar /* time_slice */)
|
||||
{
|
||||
Fail("HeatWatcher::WatchSimulation -- heat.cpp not yet reconstructed");
|
||||
Check(this);
|
||||
|
||||
HeatableSubsystem
|
||||
*watched = (HeatableSubsystem *)watchedLink.Resolve();
|
||||
if (watched == NULL)
|
||||
{
|
||||
heatAlarm.SetLevel(0);
|
||||
return;
|
||||
}
|
||||
|
||||
Scalar
|
||||
temperature = watched->CurrentTemperatureOf();
|
||||
|
||||
if (temperature > failureTemperature)
|
||||
{
|
||||
heatAlarm.SetLevel(2); // FailureHeat
|
||||
}
|
||||
else if (temperature > degradationTemperature)
|
||||
{
|
||||
heatAlarm.SetLevel(1); // DegradationHeat
|
||||
}
|
||||
else
|
||||
{
|
||||
heatAlarm.SetLevel(0); // NormalHeat
|
||||
}
|
||||
}
|
||||
|
||||
//###########################################################################
|
||||
|
||||
@@ -117,6 +117,11 @@
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Local Data
|
||||
//
|
||||
public:
|
||||
Scalar
|
||||
CurrentTemperatureOf()
|
||||
{ Check(this); return currentTemperature; }
|
||||
|
||||
protected:
|
||||
Scalar currentTemperature;
|
||||
Scalar heatLoad;
|
||||
@@ -204,6 +209,19 @@
|
||||
//
|
||||
virtual void
|
||||
DeathReset(Logical full_reset);
|
||||
|
||||
//
|
||||
// The class-typed Performance shim, the same shape every sibling
|
||||
// subsystem carries (the base takes the Subsystem-typed pointer).
|
||||
//
|
||||
typedef void
|
||||
(HeatWatcher::*Performance)(Scalar time_slice);
|
||||
void
|
||||
SetPerformance(Performance performance)
|
||||
{
|
||||
Check(this);
|
||||
activePerformance = (Simulation::Performance)performance;
|
||||
}
|
||||
void
|
||||
WatchSimulation(Scalar time_slice);
|
||||
|
||||
|
||||
@@ -794,7 +794,15 @@ PowerWatcher::PowerWatcher(
|
||||
// constant is a tuning value (stored 1:1 here until located).
|
||||
//
|
||||
minVoltage = subsystem_resource->minVoltagePercent;
|
||||
Check_Fpu();
|
||||
//
|
||||
// Install the per-frame watchdog on the master instance.
|
||||
//
|
||||
if (owner->GetInstance() != Entity::ReplicantInstance)
|
||||
{
|
||||
SetPerformance(&PowerWatcher::Simulation);
|
||||
}
|
||||
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
PowerWatcher::~PowerWatcher()
|
||||
@@ -830,10 +838,48 @@ void
|
||||
}
|
||||
|
||||
//
|
||||
// Per-frame supply-voltage watchdog. Not yet reconstructed.
|
||||
// @004b181c -- the registered Performance wrapper; the body is UpdateWatch.
|
||||
//
|
||||
// The watchdog MIRRORS the watched subsystem's electrical state -- this is
|
||||
// what drives ElectricalStateLevel()==Ready on the Torso (the twist-rate
|
||||
// power gate) and the searchlight/thermal-sight voltage reads -- with one
|
||||
// override: a subsystem reading Ready off a SAGGING source (measured
|
||||
// voltage at or under minVoltage of the source's rating) shows level 1,
|
||||
// the brownout.
|
||||
//
|
||||
void
|
||||
PowerWatcher::Simulation(Scalar)
|
||||
PowerWatcher::UpdateWatch()
|
||||
{
|
||||
Fail("PowerWatcher::Simulation -- powersub.cpp not yet reconstructed");
|
||||
Check(this);
|
||||
|
||||
WatchSimulation(0.0f); // the heat-alarm mirror first
|
||||
|
||||
PoweredSubsystem
|
||||
*watched = (PoweredSubsystem *)watchedLink.Resolve();
|
||||
if (watched == NULL)
|
||||
{
|
||||
watchdogAlarm.SetLevel(0);
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned
|
||||
level = watched->GetVoltageState();
|
||||
watchdogAlarm.SetLevel(level);
|
||||
|
||||
Generator
|
||||
*source = (Generator *)watched->ResolveVoltageSource();
|
||||
if (
|
||||
level == PoweredSubsystem::Ready &&
|
||||
source != NULL &&
|
||||
source->MeasuredVoltage() <= minVoltage * source->RatedVoltageOf()
|
||||
)
|
||||
{
|
||||
watchdogAlarm.SetLevel(1); // the brownout
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PowerWatcher::Simulation(Scalar /* time_slice */)
|
||||
{
|
||||
UpdateWatch();
|
||||
}
|
||||
|
||||
@@ -311,6 +311,28 @@
|
||||
);
|
||||
~PowerWatcher();
|
||||
|
||||
public:
|
||||
//
|
||||
// The per-frame watch body (@004b181c's Performance calls it): mirror
|
||||
// the watched subsystem's electrical state, with the brownout
|
||||
// override.
|
||||
//
|
||||
|
||||
//
|
||||
// The class-typed Performance shim, the same shape every sibling
|
||||
// subsystem carries (the base takes the Subsystem-typed pointer).
|
||||
//
|
||||
typedef void
|
||||
(PowerWatcher::*Performance)(Scalar time_slice);
|
||||
void
|
||||
SetPerformance(Performance performance)
|
||||
{
|
||||
Check(this);
|
||||
activePerformance = (Simulation::Performance)performance;
|
||||
}
|
||||
void
|
||||
UpdateWatch();
|
||||
|
||||
protected:
|
||||
Scalar minVoltage;
|
||||
AlarmIndicator watchdogAlarm;
|
||||
|
||||
Reference in New Issue
Block a user