Files
track-core/tests/track_core_tests.cpp
T
crosstyan 7b0f6a523d feat(emulator): add editable training schema panel
Redesign the DearPyGui emulator into a two-column layout with an interactive training schema editor and runtime preview.

Add JSON load/save support for ST, SM, MT, and RSMT schemes, including draft normalization, conversion to core schemes, and explicit Apply validation so intermediate edits do not restart or block the preview.

Update manual mode to clamp negative mileage, remove speed from manual positioning, preserve stopped runtime state when reloading schemas, and keep linear rendering visible with span-based drawing.

Fix the core linear pingpong render plan so reverse travel remains visible near endpoints and prefix/postfix colors stay tied to physical sides instead of reversing with heading.

Add C++ and Python regressions for schema conversion, emulator edit behavior, manual mode, linear endpoint visibility, and fixed prefix/postfix colors.
2026-05-18 17:23:00 +08:00

588 lines
25 KiB
C++

#include <cmath>
#include <cstdlib>
#include <iostream>
#include <vector>
#include "track_core/memory_strip.hpp"
#include "track_core/pid_program.hpp"
#include "track_core/pid_runtime.hpp"
#include "track_core/scheme_decoder.hpp"
#include "track_core/scheme_runtime.hpp"
namespace {
void require(bool condition, const char *message) {
if (!condition) {
std::cerr << "FAIL: " << message << '\n';
std::exit(1);
}
}
void require_eq_u32(std::uint32_t actual, std::uint32_t expected, const char *message) {
if (actual != expected) {
std::cerr << "FAIL: " << message << ": actual=" << actual << " expected=" << expected << '\n';
std::exit(1);
}
}
void require_near(float actual, float expected, float tolerance, const char *message) {
if (std::fabs(actual - expected) > tolerance) {
std::cerr << "FAIL: " << message << ": actual=" << actual << " expected=" << expected << '\n';
std::exit(1);
}
}
track_core::TrackInfo running_info(track_core::Color color = track_core::Color::green()) {
return {
.kind = track_core::SchemeKind::speed_input_time_segmented_mileage_free,
.color = color,
.id = 1,
.is_running = true,
.num_segments = 1,
};
}
void test_circular_render_wraps() {
track_core::TrackConfig config{
.draw_kind = track_core::TrackDrawKind::circular,
.line_length_m = 10.0F,
.active_line_length_m = 4.0F,
.head_offset_m = 0.0F,
.line_leds_num = 20,
};
const track_core::TrackReport report{
.id = 1,
.state = track_core::TrackState::run,
.mileage_m = 8.5F,
.speed_m_s = 1.0F,
};
const auto plan = track_core::make_track_render_plan(config, running_info(), report);
require_eq_u32(static_cast<std::uint32_t>(plan.span_count), 2, "circular span count");
require_eq_u32(plan.spans[0].start_led, 17, "circular span 0 start");
require_eq_u32(plan.spans[0].led_count, 3, "circular span 0 count");
require(plan.spans[0].color == track_core::Color::green(), "circular span 0 color");
require_eq_u32(plan.spans[1].start_led, 0, "circular span 1 start");
require_eq_u32(plan.spans[1].led_count, 5, "circular span 1 count");
}
void test_linear_render_forward_and_memory_strip() {
track_core::TrackConfig config{
.draw_kind = track_core::TrackDrawKind::linear,
.line_length_m = 10.0F,
.active_line_length_m = 4.0F,
.head_offset_m = 0.0F,
.line_leds_num = 20,
};
const track_core::TrackReport report{
.id = 2,
.state = track_core::TrackState::run,
.mileage_m = 5.0F,
.speed_m_s = 2.0F,
};
track_core::MemoryStrip strip(config.line_leds_num);
const auto plan = track_core::make_track_render_plan(config, running_info(track_core::Color::red()), report);
const auto applied = track_core::apply_render_plan(strip, plan);
require(applied == track_core::TrackError::ok, "linear plan applies");
require_eq_u32(static_cast<std::uint32_t>(plan.span_count), 4, "linear span count");
require_eq_u32(plan.spans[0].start_led, 10, "linear span 0 start");
require_eq_u32(plan.spans[0].led_count, 2, "linear span 0 count");
require(plan.spans[0].color == track_core::Color::red(), "linear span 0 color");
require_eq_u32(plan.spans[1].start_led, 12, "linear span 1 start");
require(plan.spans[1].color == track_core::Color::blue(), "linear span 1 color");
require_eq_u32(plan.spans[2].start_led, 6, "linear span 2 start");
require(plan.spans[2].color == track_core::Color::cyan(), "linear span 2 color");
require_eq_u32(plan.spans[3].start_led, 8, "linear span 3 start");
require(plan.spans[3].color == track_core::Color::red(), "linear span 3 color");
}
void test_linear_render_reverse() {
track_core::TrackConfig config{
.draw_kind = track_core::TrackDrawKind::linear,
.line_length_m = 10.0F,
.active_line_length_m = 5.0F,
.head_offset_m = 0.0F,
.line_leds_num = 20,
};
const track_core::TrackReport report{
.id = 3,
.state = track_core::TrackState::run,
.mileage_m = 15.0F,
.speed_m_s = 2.0F,
};
const auto plan = track_core::make_track_render_plan(config, running_info(track_core::Color::red()), report);
require_eq_u32(static_cast<std::uint32_t>(plan.span_count), 4, "reverse span count");
require_eq_u32(plan.spans[0].start_led, 10, "reverse span 0 start");
require_eq_u32(plan.spans[0].led_count, 3, "reverse span 0 count");
require(plan.spans[0].color == track_core::Color::red(), "reverse span 0 color");
require_eq_u32(plan.spans[1].start_led, 13, "reverse span 1 start");
require_eq_u32(plan.spans[1].led_count, 2, "reverse span 1 count");
require(plan.spans[1].color == track_core::Color::blue(), "reverse span 1 color");
require_eq_u32(plan.spans[2].start_led, 5, "reverse span 2 start");
require_eq_u32(plan.spans[2].led_count, 2, "reverse span 2 count");
require(plan.spans[2].color == track_core::Color::cyan(), "reverse span 2 color");
require_eq_u32(plan.spans[3].start_led, 7, "reverse span 3 start");
require_eq_u32(plan.spans[3].led_count, 3, "reverse span 3 count");
require(plan.spans[3].color == track_core::Color::red(), "reverse span 3 color");
}
void test_linear_render_prefix_postfix_colors_do_not_reverse() {
track_core::TrackConfig config{
.draw_kind = track_core::TrackDrawKind::linear,
.line_length_m = 10.0F,
.active_line_length_m = 5.0F,
.head_offset_m = 0.0F,
.line_leds_num = 20,
};
const track_core::TrackReport forward_report{
.id = 3,
.state = track_core::TrackState::run,
.mileage_m = 5.0F,
.speed_m_s = 2.0F,
};
const track_core::TrackReport reverse_report{
.id = 3,
.state = track_core::TrackState::run,
.mileage_m = 15.0F,
.speed_m_s = 2.0F,
};
const auto forward_plan = track_core::make_track_render_plan(config, running_info(track_core::Color::red()), forward_report);
const auto reverse_plan = track_core::make_track_render_plan(config, running_info(track_core::Color::red()), reverse_report);
require_eq_u32(static_cast<std::uint32_t>(forward_plan.span_count), static_cast<std::uint32_t>(reverse_plan.span_count), "linear same-position span count");
for (std::size_t i = 0; i < forward_plan.span_count; ++i) {
require_eq_u32(forward_plan.spans[i].start_led, reverse_plan.spans[i].start_led, "linear same-position span start");
require_eq_u32(forward_plan.spans[i].led_count, reverse_plan.spans[i].led_count, "linear same-position span count");
require(forward_plan.spans[i].color == reverse_plan.spans[i].color, "linear same-position span color");
}
}
void test_linear_render_reverse_near_ends_stays_visible() {
track_core::TrackConfig config{
.draw_kind = track_core::TrackDrawKind::linear,
.line_length_m = 10.0F,
.active_line_length_m = 4.0F,
.head_offset_m = 0.0F,
.line_leds_num = 20,
};
const auto info = running_info(track_core::Color::red());
const auto require_visible = [&](float mileage_m, const char *message) {
const track_core::TrackReport report{
.id = 4,
.state = track_core::TrackState::run,
.mileage_m = mileage_m,
.speed_m_s = 2.0F,
};
const auto plan = track_core::make_track_render_plan(config, info, report);
std::uint32_t total_leds = 0;
for (std::size_t i = 0; i < plan.span_count; ++i) {
total_leds += plan.spans[i].led_count;
}
require(total_leds > 0, message);
};
require_visible(10.1F, "reverse render visible just after right-end bounce");
require_visible(19.9F, "reverse render visible just before left-end return");
}
void test_linear_render_boundaries_apply() {
track_core::TrackConfig config{
.draw_kind = track_core::TrackDrawKind::linear,
.line_length_m = 10.0F,
.active_line_length_m = 4.0F,
.head_offset_m = 0.0F,
.line_leds_num = 20,
};
const auto info = running_info(track_core::Color::red());
for (const float mileage : {
-20.0F, -10.1F, -10.0F, -9.9F, -1.0F, -0.1F,
0.0F, 0.1F, 1.0F, 9.9F, 10.0F, 10.1F,
19.9F, 20.0F, 20.1F, 29.9F, 30.0F, 30.1F,
40.0F,
}) {
const track_core::TrackReport report{
.id = 4,
.state = track_core::TrackState::run,
.mileage_m = mileage,
.speed_m_s = 2.0F,
};
track_core::MemoryStrip strip(config.line_leds_num);
const auto plan = track_core::make_track_render_plan(config, info, report);
require(plan.span_count <= track_core::TrackRenderPlan::max_spans, "linear boundary span capacity");
for (std::size_t i = 0; i < plan.span_count; ++i) {
const auto &span = plan.spans[i];
require(span.start_led < config.line_leds_num, "linear boundary span start in range");
require(span.start_led + span.led_count <= config.line_leds_num, "linear boundary span end in range");
}
require(
track_core::apply_render_plan(strip, plan) == track_core::TrackError::ok,
"linear boundary plan applies");
}
}
void test_memory_strip_bounds() {
track_core::MemoryStrip strip(4);
require(strip.fill(0, 0, track_core::Color::red()) == track_core::TrackError::ok, "zero fill");
require(strip.fill(2, 8, track_core::Color::blue()) == track_core::TrackError::ok, "clamped fill");
require(strip.pixels()[2] == track_core::Color::blue(), "clamped fill pixel 2");
require(strip.pixels()[3] == track_core::Color::blue(), "clamped fill pixel 3");
require(strip.fill(4, 1, track_core::Color::red()) == track_core::TrackError::range, "out-of-range fill");
}
void test_scheme_decoder() {
const std::vector<std::uint8_t> data{
static_cast<std::uint8_t>(track_core::SchemeKind::speed_input_time_segmented_mileage_free),
static_cast<std::uint8_t>(track_core::AccelerationProfile::instant),
2,
0, 0, 0,
51, 10, 0,
};
const auto decoded = track_core::decode_scheme(7, track_core::Color::white(), data);
require(decoded.has_value(), "decode ST scheme");
require(decoded->id == 7, "decoded id");
require(decoded->kind == track_core::SchemeKind::speed_input_time_segmented_mileage_free, "decoded kind");
const auto *segments = std::get_if<std::vector<track_core::STSegment>>(&decoded->segments);
require(segments != nullptr, "decoded ST segment vector");
require_eq_u32(static_cast<std::uint32_t>(segments->size()), 2, "decoded ST segment count");
require_near((*segments)[1].speed_m_s, 2.0F, 0.01F, "decoded ST speed");
require_eq_u32((*segments)[1].time_since_start_s, 10, "decoded ST time");
}
void test_pid_program_constant() {
track_core::TrackPidConfig config;
config.schemas = {
track_core::TrackPidSchema{track_core::TrackConstantSegment{
.duration_s = 2,
.speed_m_s = 1.5F,
}},
};
const auto start = track_core::clock::time_point(std::chrono::seconds(0));
track_core::TrackPidProgramState state(start, config);
require_near(state.next(start + std::chrono::seconds(1), std::nullopt), 1.5F, 0.0001F, "constant PID speed");
require(!state.is_finished(start + std::chrono::seconds(1)), "constant PID not finished");
require(state.is_finished(start + std::chrono::seconds(2)), "constant PID finished");
}
track_core::TrackPidConfig pid_runtime_config() {
track_core::TrackPidConfig config;
config.band_id = 5;
config.target_hr_bpm = 148;
config.deadzone_bpm = 3;
config.schemas = {
track_core::TrackPidSchema{track_core::TrackPidSegment{
.duration_s = 45,
.min_speed_m_s = 0.0F,
.max_speed_m_s = 4.0F,
.kp = 1.0F,
.ki = 2.0F,
.kd = 0.0F,
.slew_rate_limit = 0.25F,
.fine_tune = std::nullopt,
}},
};
return config;
}
track_core::TrackPidConfig constant_pid_runtime_config(float speed_m_s) {
track_core::TrackPidConfig config;
config.band_id = 5;
config.target_hr_bpm = 148;
config.deadzone_bpm = 3;
config.schemas = {
track_core::TrackPidSchema{track_core::TrackConstantSegment{
.duration_s = 2,
.speed_m_s = speed_m_s,
}},
};
return config;
}
track_core::TrackPidBandSnapshot band_sample(std::uint32_t seq, std::uint8_t heart_rate = 140) {
return {
.band_id = 5,
.heart_rate = heart_rate,
.heart_rate_sample_seq = seq,
.has_heart_rate = true,
.hr_is_fresh = true,
.step_count = 0,
.has_step_count = false,
.band_is_active = true,
};
}
void test_pid_runtime_consumes_each_hr_sample_once() {
track_core::PidHrRuntime runtime(pid_runtime_config());
const auto start = track_core::clock::time_point(std::chrono::seconds(0));
runtime.start(start);
runtime.tick(nullptr, band_sample(1), start + std::chrono::milliseconds(1));
const auto first_status = runtime.pid_status(band_sample(1), start + std::chrono::milliseconds(1));
require_near(first_status.effective_speed_m_s, 0.25F, 0.0001F, "pid runtime first effective speed");
require_near(first_status.base_speed_m_s, 0.25F, 0.0001F, "pid runtime first base speed");
runtime.tick(nullptr, band_sample(1), start + std::chrono::milliseconds(2));
const auto repeated_status = runtime.pid_status(band_sample(1), start + std::chrono::milliseconds(2));
require_near(
repeated_status.effective_speed_m_s,
first_status.effective_speed_m_s,
0.0001F,
"pid runtime ignores repeated sample effective speed");
require_near(
repeated_status.base_speed_m_s,
first_status.base_speed_m_s,
0.0001F,
"pid runtime ignores repeated sample base speed");
runtime.tick(nullptr, band_sample(2), start + std::chrono::milliseconds(3));
const auto second_status = runtime.pid_status(band_sample(2), start + std::chrono::milliseconds(3));
require(second_status.effective_speed_m_s > repeated_status.effective_speed_m_s, "pid runtime consumes new sample");
require(second_status.base_speed_m_s > repeated_status.base_speed_m_s, "pid runtime updates base speed on new sample");
}
void test_pid_runtime_suppression_is_explicitly_configured() {
auto config = constant_pid_runtime_config(1.0F);
config.speed_suppression = track_core::TrackPidSpeedSuppression{
.ratio_min = 0.25F,
.sigma_m = 0.01F,
};
const track_core::TrackConfig track_config{
.draw_kind = track_core::TrackDrawKind::circular,
.line_length_m = 0.1F,
.active_line_length_m = 0.025F,
.head_offset_m = 0.0F,
.line_leds_num = 100,
};
const auto start = track_core::clock::time_point(std::chrono::seconds(0));
track_core::PidHrRuntime without_config(config);
without_config.start(start);
without_config.tick(nullptr, {}, start + std::chrono::milliseconds(1));
auto status = without_config.pid_status({}, start + std::chrono::milliseconds(1));
require_near(status.effective_speed_m_s, 1.0F, 0.0001F, "pid runtime skips suppression without track config");
require_near(status.base_speed_m_s, 1.0F, 0.0001F, "pid runtime base speed without track config");
track_core::PidHrRuntime with_config(config);
with_config.start(start);
with_config.tick(&track_config, {}, start + std::chrono::milliseconds(1));
status = with_config.pid_status({}, start + std::chrono::milliseconds(1));
require(status.active_segment_kind == track_core::TrackPidStageKind::constant, "pid runtime constant stage kind");
require_near(status.effective_speed_m_s, 0.25F, 0.0001F, "pid runtime suppresses at seam");
require_near(status.base_speed_m_s, 1.0F, 0.0001F, "pid runtime base speed at seam");
}
void test_pid_runtime_applies_live_tuning() {
track_core::PidHrRuntime runtime(pid_runtime_config());
const auto start = track_core::clock::time_point(std::chrono::seconds(0));
runtime.start(start);
runtime.tick(nullptr, band_sample(1), start + std::chrono::milliseconds(1));
const track_core::TrackPidRuntimeCommand command{
.command = track_core::TrackPidSetTuning{
.min_speed_m_s = 1.2F,
.max_speed_m_s = 3.5F,
.kp = 0.5F,
.ki = 0.25F,
.kd = 0.0F,
.slew_rate_limit = 0.25F,
.fine_tune = std::nullopt,
},
};
const auto applied = runtime.apply_pid_runtime_command(command, nullptr);
require(applied.has_value(), "pid runtime applies tuning");
require_near(
std::get<track_core::TrackPidSegment>(runtime.pid_config().schemas.front().segment).min_speed_m_s,
1.2F,
0.0001F,
"pid runtime config tracks tuning");
const auto status = runtime.pid_status(band_sample(1), start + std::chrono::milliseconds(1));
require_near(status.effective_speed_m_s, 1.2F, 0.0001F, "pid runtime tuned effective speed");
require_near(status.base_speed_m_s, 1.2F, 0.0001F, "pid runtime tuned base speed");
}
track_core::TrackConfig runtime_config() {
return {
.draw_kind = track_core::TrackDrawKind::circular,
.line_length_m = 5.0F,
.active_line_length_m = 1.0F,
.head_offset_m = 0.0F,
.line_leds_num = 50,
};
}
void test_speed_mileage_runtime_ticks() {
auto runtime = track_core::make_scheme_track_runtime(track_core::make_speed_mileage_scheme(
11,
track_core::Color::red(),
track_core::AccelerationProfile::instant,
{
track_core::SMSegment{.speed_m_s = 1.0F, .mileage_from_start_m = 0},
track_core::SMSegment{.speed_m_s = 2.0F, .mileage_from_start_m = 5},
track_core::SMSegment{.speed_m_s = 1.0F, .mileage_from_start_m = 10},
}));
require(runtime.has_value(), "SM runtime builds");
auto track = track_core::start_scheme_track(std::move(*runtime));
track = track_core::tick_scheme_track(runtime_config(), std::move(track), 6.0F);
const auto report = track_core::scheme_track_report(track);
require(report.state == track_core::TrackState::run, "SM still running before end");
require_near(report.mileage_m, 6.0F, 0.001F, "SM mileage after tick");
require_near(report.speed_m_s, 2.0F, 0.001F, "SM speed after boundary");
}
void test_mileage_time_runtime_ticks() {
auto runtime = track_core::make_scheme_track_runtime(track_core::make_mileage_time_scheme(
12,
track_core::Color::green(),
track_core::AccelerationProfile::instant,
{
track_core::MTSegment{.mileage_to_travel_this_segment_m = 10, .time_since_start_s = 0},
track_core::MTSegment{.mileage_to_travel_this_segment_m = 20, .time_since_start_s = 5},
track_core::MTSegment{.mileage_to_travel_this_segment_m = 1, .time_since_start_s = 15},
}));
require(runtime.has_value(), "MT runtime builds");
auto track = track_core::start_scheme_track(std::move(*runtime));
track = track_core::tick_scheme_track(runtime_config(), std::move(track), 2.0F);
auto report = track_core::scheme_track_report(track);
require_near(report.speed_m_s, 2.0F, 0.001F, "MT initial derived speed");
require_near(report.mileage_m, 4.0F, 0.001F, "MT mileage after first tick");
track = track_core::tick_scheme_track(runtime_config(), std::move(track), 4.0F);
report = track_core::scheme_track_report(track);
require_near(report.speed_m_s, 2.0F, 0.001F, "MT speed after first time boundary");
require_near(report.mileage_m, 12.0F, 0.001F, "MT mileage after boundary tick");
}
void test_speed_time_runtime_ticks() {
auto runtime = track_core::make_scheme_track_runtime(track_core::make_speed_time_scheme(
13,
track_core::Color::blue(),
track_core::AccelerationProfile::instant,
{
track_core::STSegment{.speed_m_s = 1.0F, .time_since_start_s = 0},
track_core::STSegment{.speed_m_s = 3.0F, .time_since_start_s = 5},
track_core::STSegment{.speed_m_s = 1.0F, .time_since_start_s = 10},
}));
require(runtime.has_value(), "ST runtime builds");
auto track = track_core::start_scheme_track(std::move(*runtime));
track = track_core::tick_scheme_track(runtime_config(), std::move(track), 6.0F);
const auto report = track_core::scheme_track_report(track);
require(report.state == track_core::TrackState::run, "ST still running before end");
require_near(report.mileage_m, 6.0F, 0.001F, "ST mileage after tick");
require_near(report.speed_m_s, 3.0F, 0.001F, "ST speed after time boundary");
}
void test_repeated_speed_mileage_time_runtime_ticks() {
auto runtime = track_core::make_scheme_track_runtime(track_core::make_repeated_speed_mileage_time_scheme(
14,
track_core::Color::white(),
track_core::AccelerationProfile::instant,
{
track_core::RepeatedSMSegment{
.speed_mileage_segments = {
track_core::SMSegment{.speed_m_s = 1.0F, .mileage_from_start_m = 0},
track_core::SMSegment{.speed_m_s = 2.0F, .mileage_from_start_m = 5},
},
.time_since_start_s = 0,
},
track_core::RepeatedSMSegment{
.speed_mileage_segments = {
track_core::SMSegment{.speed_m_s = 3.0F, .mileage_from_start_m = 0},
track_core::SMSegment{.speed_m_s = 1.0F, .mileage_from_start_m = 5},
},
.time_since_start_s = 4,
},
track_core::RepeatedSMSegment{
.speed_mileage_segments = {
track_core::SMSegment{.speed_m_s = 1.0F, .mileage_from_start_m = 0},
track_core::SMSegment{.speed_m_s = 1.0F, .mileage_from_start_m = 5},
},
.time_since_start_s = 20,
},
}));
require(runtime.has_value(), "RSMT runtime builds");
auto track = track_core::start_scheme_track(std::move(*runtime));
track = track_core::tick_scheme_track(runtime_config(), std::move(track), 3.0F);
track = track_core::tick_scheme_track(runtime_config(), std::move(track), 2.0F);
require_eq_u32(static_cast<std::uint32_t>(track.state.primary_segment_index), 0, "RSMT waits for line alignment");
track = track_core::tick_scheme_track(runtime_config(), std::move(track), 1.0F);
require_eq_u32(static_cast<std::uint32_t>(track.state.primary_segment_index), 1, "RSMT switches on alignment");
require_near(track.state.speed_m_s, 3.0F, 0.001F, "RSMT switched speed");
}
void test_scheme_training_runtime_renders() {
track_core::SchemeTrainingRuntime runtime;
const auto added = runtime.add_scheme(track_core::make_speed_time_scheme(
15,
track_core::Color::green(),
track_core::AccelerationProfile::instant,
{
track_core::STSegment{.speed_m_s = 1.0F, .time_since_start_s = 0},
track_core::STSegment{.speed_m_s = 1.0F, .time_since_start_s = 10},
}));
require(added.has_value(), "training runtime accepts scheme");
runtime.start();
runtime.tick(runtime_config(), 1.0F);
const auto pixels = runtime.render_pixels(runtime_config());
require(pixels.has_value(), "training runtime renders pixels");
require_eq_u32(static_cast<std::uint32_t>(pixels->size()), runtime_config().line_leds_num, "training runtime pixel count");
track_core::MemoryStrip strip(runtime_config().line_leds_num);
const auto rendered = runtime.render_to(runtime_config(), track_core::make_memory_strip_sink(strip));
require(rendered.has_value(), "training runtime renders to sink");
for (std::size_t i = 0; i < pixels->size(); ++i) {
require((*pixels)[i] == strip.pixels()[i], "render_to matches render_pixels");
}
require(!runtime.all_stopped(), "training runtime running");
require_eq_u32(runtime.state_collection().states[0].id, 15, "training runtime report id");
}
} // namespace
int main() {
test_circular_render_wraps();
test_linear_render_forward_and_memory_strip();
test_linear_render_reverse();
test_linear_render_prefix_postfix_colors_do_not_reverse();
test_linear_render_reverse_near_ends_stays_visible();
test_linear_render_boundaries_apply();
test_memory_strip_bounds();
test_scheme_decoder();
test_pid_program_constant();
test_pid_runtime_consumes_each_hr_sample_once();
test_pid_runtime_suppression_is_explicitly_configured();
test_pid_runtime_applies_live_tuning();
test_speed_mileage_runtime_ticks();
test_mileage_time_runtime_ticks();
test_speed_time_runtime_ticks();
test_repeated_speed_mileage_time_runtime_ticks();
test_scheme_training_runtime_renders();
std::cout << "track-core tests passed\n";
return 0;
}