Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
data/**/*.csv filter=lfs diff=lfs merge=lfs -text
23 changes: 23 additions & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,29 @@ module(
name = "bazel_apogeum",
version = "0.1.0",
)

bazel_dep(name = "eigen", version = "4.0.0-20241125.bcr.2")
bazel_dep(name = "googletest", version = "1.17.0.bcr.2", repo_name = "com_google_googletest")
bazel_dep(name = "rules_cc", version = "0.0.17")

# Importujemy regułę do pobierania paczek
http_archive = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_archive(
name = "moje_wielkie_dane",
url = "https://github.com/Simba-Avionic/srp-common/releases/download/v1.0/data.zip",
integrity = "sha256-1vPb5VyAvPpXCEAbIfftT7OJgjA9yYpdkZSrbALR3Jw=",
patch_cmds = [
"rm -f data/BUILD.bazel data/BUILD",
],
build_file_content = """
filegroup(
name = "data_files",
srcs = glob([
"**/*.csv",
"**/*.txt",
]),
visibility = ["//visibility:public"],
)
""",
)
17 changes: 14 additions & 3 deletions MODULE.bazel.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
INSTRUKCJA DO TESTOWANIA WIELU PLIKÓW DO WYKRYWANIA APOGEUM:
dane powinny znajdywać się w folderze /data w własnym folderze
muszą być nazwane accelerometer.csv i barometer.csv
na każdą parę musi być inny folder
Program odpalać bazel run //app:testy

żeby ręcznie odpalić testy należy teraz w folderze data utworzyć podane pliki data
Empty file removed WORKSPACE
Empty file.
28 changes: 25 additions & 3 deletions app/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,15 +1,37 @@
load("@rules_cc//cc:defs.bzl", "cc_binary")
load("@rules_cc//cc:defs.bzl", "cc_test")

cc_binary(
cc_test(
name = "main",
srcs = ["main.cpp"],
deps = ["//lib:apogee_lib"],
data = ["//data:data_files"],
)

cc_binary(
cc_test(
name = "csv_apogee_test",
srcs = ["apogee.cpp"],
deps = ["//lib:apogee_lib"],
data = ["//data:data_files"],
)

cc_test(
name = "testy",
srcs = ["testy.cpp"],
data = [
":csv_apogee_test",
],
)

cc_test(
name = "test-cc",
srcs = [
"apogee_detector_test.cc"
],
visibility = ["//visibility:public"],
deps = [
"@com_google_googletest//:gtest_main",
"//lib:apogee_lib",
"@bazel_tools//tools/cpp/runfiles",
],
data = ["@moje_wielkie_dane//:data_files"],
)
100 changes: 53 additions & 47 deletions app/apogee.cpp
Original file line number Diff line number Diff line change
@@ -1,74 +1,80 @@
#include <iostream>
#include <fstream>
#include <Eigen/Dense>
#include <vector>
#include <cmath> // dodane do std::abs
#include "lib/Matrix.h"
#include "lib/KalmanFilterR7.h"
#include "lib/ApogeeDetector.h"
#include "lib/DataLoader.h"

std::vector<double> readColumnCSV(const std::string& path, size_t colIndex) {
std::vector<double> data;

try {
if (path.find("accelerometer") != std::string::npos) {
CsvReader<double, double, double, double> csvReader(path);
for (size_t i = 0; i < csvReader.rowCount(); ++i) {
auto row = csvReader[i];
switch (colIndex) {
case 0: data.push_back(row.template get<0>()); break;
case 1: data.push_back(row.template get<1>()); break;
case 2: data.push_back(row.template get<2>()); break;
case 3: data.push_back(row.template get<3>()); break;
default: break;
}
}
} else if (path.find("barometer") != std::string::npos) {
CsvReader<double, double> csvReader(path);
for (size_t i = 0; i < csvReader.rowCount(); ++i) {
auto row = csvReader[i];
switch (colIndex) {
case 0: data.push_back(row.template get<0>()); break;
case 1: data.push_back(row.template get<1>()); break;
default: break;
}
}
}
} catch (const std::exception& e) {
std::cerr << "Error reading CSV file " << path << ": " << e.what() << std::endl;
int main(int argc, char *argv[])
{
if (argc != 4 && argc != 1)
{
std::cerr << "Usage: " << argv[0] << " [barometer_file accelerometer_file config_file]\n";
return 1;
}

return data;
}

int main() {
KalmanFilterR7 kf(0.1);
RealTimeApogee apogee(15, -0.5, 0.0);
std::string barometerPath = "data/barometer.csv";
std::string accelerometerPath = "data/accelerometer.csv";
std::string configPath = "data/config.txt";

if (argc == 4) {
barometerPath = argv[1];
accelerometerPath = argv[2];
configPath = argv[3];
}

// --- 1. Aktualizacja lub generowanie config.txt ---
checkAndGenerateConfig(configPath);

const double dt = 0.1;
// --- 2. Wczytanie przygotowanego configu ---
ConfigData config = readConfig(configPath);

std::vector<double> accelData = readColumnCSV("data/accelerometer.csv", 3);
std::vector<double> pressureData = readColumnCSV("data/barometer.csv", 1);
const double dt = config.hz > 0 ? 1.0 / config.hz : 0.1;
KalmanFilterR7 kf(dt);
RealTimeApogee apogee(15, -0.5, 0.0);

if (accelData.empty() || pressureData.empty()) {
// --- 3. Wczytanie sensorów ---
std::vector<double> pressureData = readColumnCSV(barometerPath, 1);
std::vector<double> accelData = readColumnCSV(accelerometerPath, 3);

if (accelData.empty() || pressureData.empty())
{
std::cerr << "Error: data is not loaded!\n";
return 1;
}

size_t dataSize = accelData.size();

// --- 4. Główna pętla detekcji ---
for (size_t i = 0; i < dataSize; ++i) {
double t = i * dt;
double accel = accelData[i];
double pressure = pressureData[i];

Eigen::Vector2d state = kf.processMeasurement(accel, pressure);
double height = state(0);
double velocity = state(1);
Matrix state = kf.processMeasurement(accel, pressure);
double height = state(0,0);
double velocity = state(1,0);

apogee.update(height, velocity);

std::cout << "t=" << t << " s, h=" << height << " m, v=" << velocity << " m/s\n";
if (apogee.isApogeeReached()) {
double apogeeheight = apogee.getApogee();
std::cout << ">>> Wykryto Apogeum: " << height << " m w czasie t = " << t << " s, max height: " << apogeeheight << " m\n";

if (apogee.isApogeeReached()) {
std::cout << ">>> Apogee reached: " << apogee.getApogee() << " meters\n";
if (config.loaded) {
double heightError = config.max_height_clean - height;
double heightErrorPct = (heightError / config.max_height_clean) * 100.0;
double timeError = config.time_to_apogee - t;
double timeErrorPct = (timeError / config.time_to_apogee) * 100.0;

std::cout << "\n--- Porównanie z danymi referencyjnymi (Config) ---\n";
std::cout << "Prawdziwa wys. (clean): " << config.max_height_clean << " m\n";
std::cout << "Błąd wysokości: " << std::abs(heightError) << " m (" << std::abs(heightErrorPct) << "%)\n";
std::cout << "Prawdziwy czas: " << config.time_to_apogee << " s\n";
std::cout << "Błąd czasu detekcji: " << std::abs(timeError) << " s (" << std::abs(timeErrorPct) << "%)\n";
}
break;
}
}
Expand Down
Loading