Time and Clock System
> Status: PATCH · 已对齐 PCR Master Blueprint v1.0 > 范畴: src/types/Time.h > 依赖: 无(POD value type)
The foundation of the entire architecture. This system guarantees deterministic physics and zero time-drift errors.
Core Philosophy
- No Floats for Time: Floating-point addition is non-associative
(a + b) + c != a + (b + c). Accumulating smalldtover a long simulation will drift. We useint64_tticks. - Fixed Precision: The base unit is 1 tick = 0.1ms (100μs). This is sufficient for both high-frequency dynamics (1kHz+) and long-duration missions.
- Adaptive Clock: The simulation clock must support variable steps to align perfectly with critical events (e.g., IMU sampling, engine cutoff).
- No
std::chrono: 仿真的 wall clock 与 OS 时钟无关。std::chrono::steady_clock漂移、跨进程不可序列化。我们的Time是仿真域专属类型。
1. The Time Class
A value type representing a point in time or a duration.
// src/types/Time.h
#include <cstdint>
#include <compare>
#include <ostream>
class Time {
// The only data member: 0.1ms ticks
int64_t ticks_;
// Private constructor to force usage of static factories
constexpr explicit Time(int64_t t) : ticks_(t) {}
public:
// --- Factories ---
static constexpr Time zero() { return Time(0); }
static constexpr Time from_ticks(int64_t t) { return Time(t); }
static constexpr Time from_sec(double s) {
return Time(static_cast<int64_t>(s * 10000.0 + 0.5));
}
static constexpr Time from_ms(double ms) {
return Time(static_cast<int64_t>(ms * 10.0 + 0.5));
}
static constexpr Time from_hz(int hz) { // 50 Hz → 0.02s = 200 ticks
return Time(10000 / hz);
}
// --- Accessors ---
constexpr int64_t ticks() const { return ticks_; }
constexpr double to_sec() const { return ticks_ * 0.0001; }
constexpr double to_ms() const { return ticks_ * 0.1; }
// --- Arithmetic ---
constexpr Time operator+(Time other) const { return Time(ticks_ + other.ticks_); }
constexpr Time operator-(Time other) const { return Time(ticks_ - other.ticks_); }
constexpr Time operator*(int64_t s) const { return Time(ticks_ * s); }
constexpr Time operator/(int64_t s) const { return Time(ticks_ / s); }
// --- Comparison (C++20 spaceship) ---
constexpr auto operator<=>(const Time&) const = default;
// --- Output ---
friend std::ostream& operator<<(std::ostream& os, Time t) {
return os << t.to_sec() << "s";
}
};
// User-defined literals for convenience
constexpr Time operator""_s(long double s) { return Time::from_sec(static_cast<double>(s)); }
constexpr Time operator""_ms(long double ms) { return Time::from_ms(static_cast<double>(ms)); }> v1.0 增补:from_hz(int) 是必须的;调度器 sim::MultiRateScheduler 用它构造 fcc_period = Time::from_hz(50) / phys_period = Time::from_hz(1000)(详见 06_Simulation/Body_World_Tick.md §6)。
2. Clock — 仿真主时钟(在 WorldState 内)
仿真主时钟存在于 sim::WorldState.current_time,由 WorldTick 阶段 A 推进(详见 06_Simulation/Body_World_Tick.md §3.2)。没有独立的 Clock 对象——之前 v0 的 Clock 结构已废弃,因为:
- 自适应步长由
sim::MultiRateScheduler统一管理(不再 per-state) target_time概念由 mission_config.end_time 提供- IMU sampling alignment 由设备 FSM 内部完成(不再主循环对齐)
// simulation/state/WorldState.h(节选)
namespace sim {
struct WorldState {
Time current_time;
std::vector<RocketBody> bodies;
// ... 拓扑事件历史等
};
} // namespace sim3. MultiRateScheduler
详见 06_Simulation/Body_World_Tick.md §6 与 04_FCC/Static_Compilation_FSM.md。简要:
namespace sim {
struct MultiRateScheduler {
Time fcc_period { Time::from_hz(50) }; // FCC 50 Hz
Time phys_period { Time::from_hz(1000) }; // 物理 1 kHz
Time last_fcc_tick { Time::zero() };
bool should_fcc_tick(Time now); // O(1) 整数比较,决定本 phys tick 是否驱动 FCC
};
} // namespace sim> 强约束:phys_period.ticks() 必须整除 fcc_period.ticks(),否则会出现"漂移"。详见 06_Simulation/Body_World_Tick.md §6.4 频率匹配表。
4. Usage Example
// 1. Define times naturally
Time t_start = 0_s;
Time phys_dt = 1_ms;
Time mission_end = 300.5_s;
// 2. Runner main loop
sim::WorldState ws;
ws.current_time = t_start;
sim::MultiRateScheduler scheduler;
while (ws.current_time < mission_end) {
auto [wout, new_ws, log] = sim::world_tick(phys_dt).run(world_env, std::move(ws));
ws = std::move(new_ws);
// ws.current_time 已经在 world_tick 内推进了 phys_dt
}详见 07_Runtime/Assembler_and_Runner.md §4.3。
5. C-Distillation 路径
| C++ | C |
|---|---|
class Time { int64_t ticks_; } | typedef int64_t Time; 或 struct Time { int64_t ticks; }; |
operator+/- 等 | static inline Time time_add(Time a, Time b); 等 |
user-defined literals _s、_ms | 编译期 #define MS(x) ((Time){(x) * 10}) 宏 |
from_hz(int) | static inline Time time_from_hz(int hz) |
详见 08_Cross_Cutting/Implementation_Roadmap.md §7。
6. 引用
- Blueprint §0("无浮点时间" 是基础约束)、§2.7(Runtime 持有主循环)、§2.6.4(多速率调度)
06_Simulation/Body_World_Tick.md§6(MultiRateScheduler)07_Runtime/Assembler_and_Runner.md§4.3(Runner main loop 使用 Time)06_Simulation/Dual_Layer_RWS.md(BodyEnv.current_time 是 Time 类型)