Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[sysid] Error on missing tests in loaded DataLog #7747

Merged
merged 14 commits into from
Feb 4, 2025
4 changes: 3 additions & 1 deletion sysid/src/main/native/cpp/App.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,10 @@ void Application(std::string_view saveDir) {
auto analyzer = std::make_unique<sysid::Analyzer>(storage, gLogger);

logLoader->unload.connect([ds = dataSelector.get()] { ds->Reset(); });
dataSelector->testdata = [_analyzer = analyzer.get()](auto data) {
dataSelector->testdata = [_analyzer = analyzer.get(),
ds = dataSelector.get()](auto data) {
_analyzer->m_data = data;
_analyzer->SetMissingTests(ds->m_missingTests);
_analyzer->AnalyzeData();
};

Expand Down
18 changes: 18 additions & 0 deletions sysid/src/main/native/cpp/view/Analyzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <numbers>
#include <string>
#include <thread>
#include <vector>

#include <fmt/format.h>
#include <glass/Context.h>
Expand Down Expand Up @@ -251,6 +252,13 @@ void Analyzer::Display() {
}
break;
}
case AnalyzerState::kMissingTestsError: {
CreateErrorPopup(m_errorPopup, m_exception);
if (!m_errorPopup) {
m_state = AnalyzerState::kWaitingForData;
}
break;
}
case AnalyzerState::kGeneralDataError:
case AnalyzerState::kTestDurationError:
case AnalyzerState::kVelocityThresholdError: {
Expand All @@ -269,6 +277,9 @@ void Analyzer::Display() {
void Analyzer::PrepareData() {
WPI_INFO(m_logger, "{}", "Preparing data");
try {
if (m_missingTests.size() > 0) {
throw sysid::MissingTestsError{m_missingTests};
}
m_manager->PrepareData();
UpdateFeedforwardGains();
UpdateFeedbackGains();
Expand All @@ -281,6 +292,9 @@ void Analyzer::PrepareData() {
} catch (const sysid::NoDynamicDataError& e) {
m_state = AnalyzerState::kTestDurationError;
HandleError(e.what());
} catch (const sysid::MissingTestsError& e) {
m_state = AnalyzerState::kMissingTestsError;
HandleError(e.what());
} catch (const AnalysisManager::FileReadingError& e) {
m_state = AnalyzerState::kFileError;
HandleError(e.what());
Expand Down Expand Up @@ -324,6 +338,10 @@ void Analyzer::HandleError(std::string_view msg) {
PrepareRawGraphs();
}

void Analyzer::SetMissingTests(const std::vector<std::string>& missingTests) {
m_missingTests = missingTests;
}

void Analyzer::DisplayGraphs() {
ImGui::SetNextWindowPos(ImVec2{kDiagnosticPlotWindowPos},
ImGuiCond_FirstUseEver);
Expand Down
11 changes: 11 additions & 0 deletions sysid/src/main/native/cpp/view/DataSelector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include <algorithm>
#include <string>
#include <string_view>
#include <utility>
#include <vector>

Expand Down Expand Up @@ -111,6 +112,7 @@ void DataSelector::Display() {
continue;
}
WPI_INFO(m_logger, "Loaded test state {}", it2->first);
m_executedTests.insert(it2->first);
++it2;
}
if (it->second.empty()) {
Expand All @@ -132,6 +134,15 @@ void DataSelector::Display() {
return;
}

if (m_executedTests.size() < 4 && !m_testCountValidated) {
for (auto test : kValidTests) {
if (!m_executedTests.contains(test)) {
m_missingTests.push_back(test);
m_testCountValidated = true;
}
}
}

#if 0
// Test filtering
if (ImGui::BeginCombo("Test", m_selectedTest.c_str())) {
Expand Down
22 changes: 21 additions & 1 deletion sysid/src/main/native/include/sysid/analysis/FilteringUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,16 @@

#pragma once

#include <cmath>
#include <exception>
#include <functional>
#include <string>
#include <string_view>
#include <tuple>
#include <utility>
#include <vector>

#include <fmt/format.h>
#include <fmt/ranges.h>
#include <frc/filter/LinearFilter.h>
#include <units/time.h>
#include <wpi/StringMap.h>
Expand Down Expand Up @@ -68,6 +69,25 @@ class NoQuasistaticDataError : public std::exception {
}
};

/**
* Exception for not all tests being present.
*/
class MissingTestsError : public std::exception {
public:
explicit MissingTestsError(std::vector<std::string> MissingTests)
: missingTests(std::move(MissingTests)) {
errorString = fmt::format(
"The following tests were not detected: {}. Make sure to perform all "
"four tests as described in the SysId documentation.",
fmt::join(missingTests, ", "));
}
const char* what() const noexcept override { return errorString.c_str(); }

private:
std::vector<std::string> missingTests;
std::string errorString;
};

/**
* Exception for Dynamic Data being completely removed.
*/
Expand Down
8 changes: 8 additions & 0 deletions sysid/src/main/native/include/sysid/view/Analyzer.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <string>
#include <string_view>
#include <thread>
#include <vector>

#include <glass/View.h>
#include <implot.h>
Expand Down Expand Up @@ -46,6 +47,7 @@ class Analyzer : public glass::View {
kVelocityThresholdError,
kTestDurationError,
kGeneralDataError,
kMissingTestsError,
kFileError
};
/**
Expand Down Expand Up @@ -91,6 +93,11 @@ class Analyzer : public glass::View {
*/
void AnalyzeData();

/**
* Used by DataSelector to import any missing tests.
*/
void SetMissingTests(const std::vector<std::string>& missingTests);

private:
/**
* Kills the data preparation thread
Expand Down Expand Up @@ -199,6 +206,7 @@ class Analyzer : public glass::View {

// Stores the exception message.
std::string m_exception;
std::vector<std::string> m_missingTests;

bool m_calcDefaults = false;

Expand Down
7 changes: 7 additions & 0 deletions sysid/src/main/native/include/sysid/view/DataSelector.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <functional>
#include <future>
#include <map>
#include <set>
#include <string>
#include <utility>
#include <vector>
Expand Down Expand Up @@ -55,6 +56,7 @@ class DataSelector : public glass::View {
* Called when new test data is loaded.
*/
std::function<void(TestData)> testdata;
std::vector<std::string> m_missingTests;

private:
wpi::Logger& m_logger;
Expand All @@ -74,6 +76,11 @@ class DataSelector : public glass::View {
int m_selectedAnalysis = 0;
std::future<TestData> m_testdataFuture;
std::vector<std::string> m_testdataStats;
std::set<std::string> kValidTests = {"quasistatic-forward",
"quasistatic-reverse", "dynamic-forward",
"dynamic-reverse"};
std::set<std::string> m_executedTests;
bool m_testCountValidated = false;

static Tests LoadTests(const glass::DataLogReaderEntry& testStateEntry);
TestData BuildTestData();
Expand Down
Loading