From 350e65840564e2f79940cb165fd0dfd76a31fc49 Mon Sep 17 00:00:00 2001 From: mandelbroo Date: Wed, 29 Apr 2026 17:28:44 +0000 Subject: [PATCH 1/6] read a file and print it out Co-authored-by: Copilot --- homework_04/src/main.cpp | 82 +++++++++++++++++++++++++++++++--------- 1 file changed, 64 insertions(+), 18 deletions(-) diff --git a/homework_04/src/main.cpp b/homework_04/src/main.cpp index 42894b6..8ad0a3f 100644 --- a/homework_04/src/main.cpp +++ b/homework_04/src/main.cpp @@ -1,22 +1,68 @@ +#include #include +#include + +using namespace std; + +ifstream readFile(const char* filePath) { + ifstream file(filePath, ios::in); + + if (!file.is_open()) { + cerr << "Error: Could not open the file:" << filePath << endl; + exit(1); + } + + return file; +} int main(int argc, char** argv) { - if (argc != 2) { - std::cerr << "usage: ugv_odometry \n"; - return 1; - } - - // TODO: implement wheel odometry for a 4-wheel differential-drive UGV. - // - // Parameters: - // ticks_per_revolution = 1024 - // wheel_radius_m = 0.3 - // wheelbase_m = 1.0 - // - // Input: text file with 5 whitespace-separated numbers per line: - // timestamp_ms fl_ticks fr_ticks bl_ticks br_ticks - // Output: same tabular format on stdout, starting from the second sample: - // timestamp_ms x y theta - - return 0; + if (argc != 2) { + cerr << "usage: ugv_odometry " << endl; + return 1; + } + + cout << "processing file: " << argv[1] << endl; + + ifstream file = readFile(argv[1]); + string line; + + float timestamp_ms; + float fl_ticks; + float fr_ticks; + float bl_ticks; + float br_ticks; + + if (!file.is_open()) { + cerr << "Error: Could not open the file:" << argv[1] << endl; + return 1; + } + + while (std::getline(file, line)) { + getline(file, line); + istringstream ss(line); + ss >> timestamp_ms >> fl_ticks >> fr_ticks >> bl_ticks >> br_ticks; + + cout << timestamp_ms << " " << fl_ticks << " " << fr_ticks << " " << bl_ticks + << " " << br_ticks << endl; + } + file.close(); + + // int ticks_per_revolution = 1024; // 1024 ticks per wheel revolution + // float wheel_radius_m = 0.3; // 30 cm + // float wheelbase_m = 1.0; // 1 m distance between front and rear axles + // float x = 0, y = 0, theta = 0; + + // TODO: implement wheel odometry for a 4-wheel differential-drive UGV. + // + // Parameters: + // ticks_per_revolution = 1024 + // wheel_radius_m = 0.3 + // wheelbase_m = 1.0 + // + // Input: text file with 5 whitespace-separated numbers per line: + // timestamp_ms fl_ticks fr_ticks bl_ticks br_ticks + // Output: same tabular format on stdout, starting from the second sample: + // timestamp_ms x y theta + + return 0; } From a1505a6ca8fbedd162093a5f0b51bef0f15d3cf7 Mon Sep 17 00:00:00 2001 From: mandelbroo Date: Wed, 29 Apr 2026 17:52:52 +0000 Subject: [PATCH 2/6] remove redundant code for file and line reading Co-authored-by: Copilot --- homework_04/src/main.cpp | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/homework_04/src/main.cpp b/homework_04/src/main.cpp index 8ad0a3f..acbb6df 100644 --- a/homework_04/src/main.cpp +++ b/homework_04/src/main.cpp @@ -4,41 +4,29 @@ using namespace std; -ifstream readFile(const char* filePath) { - ifstream file(filePath, ios::in); - - if (!file.is_open()) { - cerr << "Error: Could not open the file:" << filePath << endl; - exit(1); - } - - return file; -} - int main(int argc, char** argv) { if (argc != 2) { cerr << "usage: ugv_odometry " << endl; return 1; } - cout << "processing file: " << argv[1] << endl; + ifstream file(argv[1], ios::in); - ifstream file = readFile(argv[1]); - string line; + if (!file.is_open()) { + cerr << "Error: Could not open the file:" << argv[1] << endl; + return 1; + } + float x = 0, y = 0, theta = 0; float timestamp_ms; float fl_ticks; float fr_ticks; float bl_ticks; float br_ticks; - if (!file.is_open()) { - cerr << "Error: Could not open the file:" << argv[1] << endl; - return 1; - } + string line; - while (std::getline(file, line)) { - getline(file, line); + while (getline(file, line)) { istringstream ss(line); ss >> timestamp_ms >> fl_ticks >> fr_ticks >> bl_ticks >> br_ticks; From e9f852189def857ba8505fbc9a50413ed8edfa0b Mon Sep 17 00:00:00 2001 From: mandelbroo Date: Wed, 29 Apr 2026 19:05:18 +0000 Subject: [PATCH 3/6] resolve the objective --- homework_04/src/main.cpp | 101 +++++++++++++++++++++++++++------------ 1 file changed, 71 insertions(+), 30 deletions(-) diff --git a/homework_04/src/main.cpp b/homework_04/src/main.cpp index acbb6df..3dce054 100644 --- a/homework_04/src/main.cpp +++ b/homework_04/src/main.cpp @@ -1,56 +1,97 @@ +#define _USE_MATH_DEFINES +#include #include #include #include +#include using namespace std; +const int TICKS_PER_REVOLUTION = 1024; // 1024 імпульсів на оберт колеса +const float WHEEL_RADIUS_M = 0.3; // 30 см +const float WHEELBASE_M = 1.0; // 1 м відстань між передньою та задньою віссю +const string OUTPUT_FILE_PATH = "output.txt"; + int main(int argc, char** argv) { if (argc != 2) { - cerr << "usage: ugv_odometry " << endl; + cerr << "Usage: ugv_odometry " << endl; return 1; } - ifstream file(argv[1], ios::in); + ifstream inputFile(argv[1], ios::in); - if (!file.is_open()) { + if (!inputFile.is_open()) { cerr << "Error: Could not open the file:" << argv[1] << endl; return 1; } - float x = 0, y = 0, theta = 0; - float timestamp_ms; - float fl_ticks; - float fr_ticks; - float bl_ticks; - float br_ticks; + std::ofstream outputFile(OUTPUT_FILE_PATH, ios::out); + + if (!outputFile.is_open()) { + cout << "Error. Cannot open output file." << endl; + return 1; + } + float x = 0, y = 0, theta = 0; + int timestamp_ms, fl_ticks, fr_ticks, bl_ticks, br_ticks; + int prev_fl_ticks, prev_fr_ticks, prev_bl_ticks, prev_br_ticks; + int index = 0; string line; - while (getline(file, line)) { + while (getline(inputFile, line)) { istringstream ss(line); ss >> timestamp_ms >> fl_ticks >> fr_ticks >> bl_ticks >> br_ticks; - cout << timestamp_ms << " " << fl_ticks << " " << fr_ticks << " " << bl_ticks - << " " << br_ticks << endl; + if (index == 0) { + index++; + prev_fl_ticks = fl_ticks; + prev_fr_ticks = fr_ticks; + prev_bl_ticks = bl_ticks; + prev_br_ticks = br_ticks; + outputFile << timestamp_ms << " " << x << " " << y << " " << theta << endl; + continue; // Пропускаємо перший елемент оскільки нам потрібен попередній зразок для обчислення різниць + } + + // Крок 1. Delta iмпульсiв по кожному колесу: + int d_fl = fl_ticks - prev_fl_ticks; + int d_fr = fr_ticks - prev_fr_ticks; + int d_bl = bl_ticks - prev_bl_ticks; + int d_br = br_ticks - prev_br_ticks; + + prev_fl_ticks = fl_ticks; + prev_fr_ticks = fr_ticks; + prev_bl_ticks = bl_ticks; + prev_br_ticks = br_ticks; + + // Крок 2. Усереднити борти (передне i заднє колесо одного боку обертаються синхронно): + int d_left = (d_fl + d_bl) / 2; + int d_right = (d_fr + d_br) / 2; + + // Крок 3. Перевести iмпульси у метри: + float distance_per_tick = 2 * M_PI * WHEEL_RADIUS_M / TICKS_PER_REVOLUTION; + float dL = d_left * distance_per_tick; + float dR = d_right * distance_per_tick; + + // Крок 4. Скiльки пройшов центр робота i на скiльки повернувся: + float d = (dL + dR) / 2; // пройдена вiдстань центру + float dtheta = (dR - dL) / WHEELBASE_M; // змiна орiєнтацiї + + // Крок 5. Оновити позицiю (midpoint integration - усереднений напрямок на кроцi): + x += d * cos(theta + dtheta / 2); + y += d * sin(theta + dtheta / 2); + theta += dtheta; + + outputFile << timestamp_ms << " " << x << " " << y << " " << theta << endl; + + index++; + prev_fl_ticks = fl_ticks; + prev_fr_ticks = fr_ticks; + prev_bl_ticks = bl_ticks; + prev_br_ticks = br_ticks; } - file.close(); - - // int ticks_per_revolution = 1024; // 1024 ticks per wheel revolution - // float wheel_radius_m = 0.3; // 30 cm - // float wheelbase_m = 1.0; // 1 m distance between front and rear axles - // float x = 0, y = 0, theta = 0; - - // TODO: implement wheel odometry for a 4-wheel differential-drive UGV. - // - // Parameters: - // ticks_per_revolution = 1024 - // wheel_radius_m = 0.3 - // wheelbase_m = 1.0 - // - // Input: text file with 5 whitespace-separated numbers per line: - // timestamp_ms fl_ticks fr_ticks bl_ticks br_ticks - // Output: same tabular format on stdout, starting from the second sample: - // timestamp_ms x y theta + + inputFile.close(); + outputFile.close(); return 0; } From 58b789008a1eda1356b611fd09aeb03b6b8f4c68 Mon Sep 17 00:00:00 2001 From: mandelbroo Date: Wed, 29 Apr 2026 19:16:58 +0000 Subject: [PATCH 4/6] review and cleanup --- homework_04/src/main.cpp | 55 +++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 29 deletions(-) diff --git a/homework_04/src/main.cpp b/homework_04/src/main.cpp index 3dce054..349ebec 100644 --- a/homework_04/src/main.cpp +++ b/homework_04/src/main.cpp @@ -7,9 +7,9 @@ using namespace std; -const int TICKS_PER_REVOLUTION = 1024; // 1024 імпульсів на оберт колеса -const float WHEEL_RADIUS_M = 0.3; // 30 см -const float WHEELBASE_M = 1.0; // 1 м відстань між передньою та задньою віссю +const float TICKS_PER_REVOLUTION = 1024.0; // 1024 імпульсів на оберт колеса +const float WHEEL_RADIUS_M = 0.3; // 30 см +const float WHEELBASE_M = 1.0; // 1 м відстань між передньою та задньою віссю const string OUTPUT_FILE_PATH = "output.txt"; int main(int argc, char** argv) { @@ -18,54 +18,51 @@ int main(int argc, char** argv) { return 1; } - ifstream inputFile(argv[1], ios::in); + fstream inputFile(argv[1], ios::in); if (!inputFile.is_open()) { cerr << "Error: Could not open the file:" << argv[1] << endl; return 1; } - std::ofstream outputFile(OUTPUT_FILE_PATH, ios::out); + fstream outputFile(OUTPUT_FILE_PATH, ios::out); if (!outputFile.is_open()) { - cout << "Error. Cannot open output file." << endl; + cerr << "Error: Could not open the output file:" << OUTPUT_FILE_PATH << endl; return 1; } + int timestamp_ms; + bool isFirstStep = true; float x = 0, y = 0, theta = 0; - int timestamp_ms, fl_ticks, fr_ticks, bl_ticks, br_ticks; - int prev_fl_ticks, prev_fr_ticks, prev_bl_ticks, prev_br_ticks; - int index = 0; + float fl_ticks, fr_ticks, bl_ticks, br_ticks; + float prev_fl_ticks, prev_fr_ticks, prev_bl_ticks, prev_br_ticks; string line; while (getline(inputFile, line)) { istringstream ss(line); ss >> timestamp_ms >> fl_ticks >> fr_ticks >> bl_ticks >> br_ticks; - if (index == 0) { - index++; + if (isFirstStep) { + isFirstStep = false; prev_fl_ticks = fl_ticks; prev_fr_ticks = fr_ticks; prev_bl_ticks = bl_ticks; prev_br_ticks = br_ticks; outputFile << timestamp_ms << " " << x << " " << y << " " << theta << endl; - continue; // Пропускаємо перший елемент оскільки нам потрібен попередній зразок для обчислення різниць + + continue; // Пропускаємо перший елемент оскільки нам потрібен два елементи для обчислення дельти } // Крок 1. Delta iмпульсiв по кожному колесу: - int d_fl = fl_ticks - prev_fl_ticks; - int d_fr = fr_ticks - prev_fr_ticks; - int d_bl = bl_ticks - prev_bl_ticks; - int d_br = br_ticks - prev_br_ticks; - - prev_fl_ticks = fl_ticks; - prev_fr_ticks = fr_ticks; - prev_bl_ticks = bl_ticks; - prev_br_ticks = br_ticks; + float d_fl = fl_ticks - prev_fl_ticks; + float d_fr = fr_ticks - prev_fr_ticks; + float d_bl = bl_ticks - prev_bl_ticks; + float d_br = br_ticks - prev_br_ticks; // Крок 2. Усереднити борти (передне i заднє колесо одного боку обертаються синхронно): - int d_left = (d_fl + d_bl) / 2; - int d_right = (d_fr + d_br) / 2; + float d_left = (d_fl + d_bl) / 2.0; + float d_right = (d_fr + d_br) / 2.0; // Крок 3. Перевести iмпульси у метри: float distance_per_tick = 2 * M_PI * WHEEL_RADIUS_M / TICKS_PER_REVOLUTION; @@ -73,25 +70,25 @@ int main(int argc, char** argv) { float dR = d_right * distance_per_tick; // Крок 4. Скiльки пройшов центр робота i на скiльки повернувся: - float d = (dL + dR) / 2; // пройдена вiдстань центру + float d = (dL + dR) / 2.0; // пройдена вiдстань центру float dtheta = (dR - dL) / WHEELBASE_M; // змiна орiєнтацiї // Крок 5. Оновити позицiю (midpoint integration - усереднений напрямок на кроцi): - x += d * cos(theta + dtheta / 2); - y += d * sin(theta + dtheta / 2); + x += d * cos(theta + dtheta / 2.0); + y += d * sin(theta + dtheta / 2.0); theta += dtheta; - outputFile << timestamp_ms << " " << x << " " << y << " " << theta << endl; - - index++; prev_fl_ticks = fl_ticks; prev_fr_ticks = fr_ticks; prev_bl_ticks = bl_ticks; prev_br_ticks = br_ticks; + outputFile << timestamp_ms << " " << x << " " << y << " " << theta << endl; } inputFile.close(); outputFile.close(); + cout << "Odometry calculation completed. Output written to: " << OUTPUT_FILE_PATH << endl; + return 0; } From d2c06952b99419b5f5dcc0075cfd478c5fd18c2e Mon Sep 17 00:00:00 2001 From: Vitalii Makarets Date: Thu, 30 Apr 2026 12:01:46 +0300 Subject: [PATCH 5/6] Update homework_04/src/main.cpp --- homework_04/src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homework_04/src/main.cpp b/homework_04/src/main.cpp index 349ebec..4b20498 100644 --- a/homework_04/src/main.cpp +++ b/homework_04/src/main.cpp @@ -51,7 +51,7 @@ int main(int argc, char** argv) { prev_br_ticks = br_ticks; outputFile << timestamp_ms << " " << x << " " << y << " " << theta << endl; - continue; // Пропускаємо перший елемент оскільки нам потрібен два елементи для обчислення дельти + continue; // Пропускаємо перший елемент оскільки нам потрібні два елементи для обчислення дельти } // Крок 1. Delta iмпульсiв по кожному колесу: From f8cc031f619bf35e017bb73099a0194da4f2df31 Mon Sep 17 00:00:00 2001 From: Vitalii Makarets Date: Thu, 30 Apr 2026 12:01:52 +0300 Subject: [PATCH 6/6] Update homework_04/src/main.cpp --- homework_04/src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homework_04/src/main.cpp b/homework_04/src/main.cpp index 4b20498..f7856ae 100644 --- a/homework_04/src/main.cpp +++ b/homework_04/src/main.cpp @@ -60,7 +60,7 @@ int main(int argc, char** argv) { float d_bl = bl_ticks - prev_bl_ticks; float d_br = br_ticks - prev_br_ticks; - // Крок 2. Усереднити борти (передне i заднє колесо одного боку обертаються синхронно): + // Крок 2. Усереднити борти (переднє i заднє колесо одного боку обертаються синхронно): float d_left = (d_fl + d_bl) / 2.0; float d_right = (d_fr + d_br) / 2.0;