项目结构大变

This commit is contained in:
2025-11-20 19:29:00 +08:00
parent 6a7ab65597
commit a8791ab3df
17 changed files with 549 additions and 287 deletions

View File

@@ -3,6 +3,7 @@
#include <vector>
#include <chrono>
#include <thread>
#include <memory>
#include <opencv2/opencv.hpp>
@@ -22,26 +23,21 @@ void output_control_data(const cv::Point2f* ballistic_point,
TTLCommunicator* ttl_communicator,
const cv::Point2f& img_center,
bool use_ttl) {
// Only send data when TTL is enabled and meets frame interval
if (use_ttl && frame_counter % 5 == 0) {
// Only send data when TTL is enabled, meets frame interval, and has valid target
if (use_ttl && frame_counter % 5 == 0 && ballistic_point != nullptr) {
std::string send_str;
if (ballistic_point != nullptr) {
// Calculate offset (based on actual image center)
int ballistic_offset_x = static_cast<int>(ballistic_point->x - img_center.x);
int ballistic_offset_y = static_cast<int>(ballistic_point->y - img_center.y);
// Calculate offset (based on actual image center)
int ballistic_offset_x = static_cast<int>(ballistic_point->x - img_center.x);
int ballistic_offset_y = static_cast<int>(img_center.y - ballistic_point->y);
// Color simplification mapping
std::string simplified_color = target_color;
if (target_color == "red") simplified_color = "r";
else if (target_color == "blue") simplified_color = "b";
// Color simplification mapping
std::string simplified_color = target_color;
if (target_color == "red") simplified_color = "r";
else if (target_color == "blue") simplified_color = "b";
// Construct send string
send_str = "s " + simplified_color + " " + std::to_string(ballistic_offset_x) + " " + std::to_string(ballistic_offset_y);
} else {
// Format when no detection result
send_str = "s u 0 0";
}
// Construct send string
send_str = "s " + simplified_color + " " + std::to_string(ballistic_offset_x) + " " + std::to_string(ballistic_offset_y);
// Send data
if (ttl_communicator != nullptr) {
@@ -58,10 +54,10 @@ void set_camera_resolution(MindVisionCamera& , int width, int height) {
}
int main(int /*argc*/, char* /*argv*/[]) {
std::string target_color = "blue";
std::string target_color = "red";
int cam_id = 0;
cv::Size default_resolution(640, 480);
bool use_ttl = false; // Set to false to disable TTL communication
bool use_ttl = true; // Set to false to disable TTL communication
// Define optional resolution list (adjust based on camera support)
std::vector<cv::Size> resolutions = {
@@ -83,9 +79,14 @@ int main(int /*argc*/, char* /*argv*/[]) {
// Initialize TTL communication (only when enabled)
TTLCommunicator* ttl = nullptr;
if (use_ttl) {
ttl = new TTLCommunicator(TTL_BAUDRATE);
if (!ttl->connect()) {
std::cout << "Warning: Cannot establish TTL connection, will continue running but not send data" << std::endl;
// On Linux, the port would typically be /dev/ttyUSB0, /dev/ttyACM0, etc.
ttl = new TTLCommunicator("/dev/ttyUSB0", TTL_BAUDRATE);
if (ttl != nullptr) {
if (!ttl->connect()) {
std::cout << "Warning: Cannot establish TTL connection, will continue running but not send data" << std::endl;
}
} else {
std::cout << "Error: Failed to create TTL communicator instance" << std::endl;
}
} else {
std::cout << "TTL communication disabled" << std::endl;
@@ -119,17 +120,23 @@ int main(int /*argc*/, char* /*argv*/[]) {
cv::Mat frame;
try {
while (true) {
if (!camera.read_frame(frame)) {
std::cout << "Cannot read from MindVision camera, exiting!" << std::endl;
// 使用新的颜色过滤方法同时获取图像和原始掩码
cv::Mat raw_mask;
if (!camera.read_frame_with_color_filter(frame, raw_mask, target_color)) {
std::cout << "Cannot read from MindVision camera, exiting!HERERER" << std::endl;
break;
}
// Get actual image size and calculate center
cv::Point2f img_center(frame.cols / 2.0f, frame.rows / 2.0f);
// Preprocessing
cv::Mat mask, color_only_frame;
preprocessor.process_frame(frame, target_color, mask, color_only_frame);
// 使用OpenCV进行形态学处理
cv::Mat mask;
preprocessor.apply_morphology(raw_mask, mask);
// 生成彩色图像(仅显示目标颜色)
cv::Mat color_only_frame;
frame.copyTo(color_only_frame, raw_mask);
// Armor plate detection
std::vector<LightBar> valid_light_bars;
@@ -142,12 +149,13 @@ int main(int /*argc*/, char* /*argv*/[]) {
current_center = &(armor_plates[0].center);
}
cv::Point2f* predicted_center = nullptr;
// Use smart pointer for safer memory management
std::unique_ptr<cv::Point2f> predicted_center = nullptr;
if (current_center != nullptr) {
// Has detection result: update Kalman filter, reset consecutive prediction count
kalman_tracker.update(*current_center);
predicted_center = new cv::Point2f(kalman_tracker.predict());
predicted_center = std::make_unique<cv::Point2f>(kalman_tracker.predict());
// Get velocity from the Kalman filter
target_speed = cv::Point2f(0.0f, 0.0f); // Kalman filter in OpenCV doesn't directly expose velocity
@@ -158,7 +166,7 @@ int main(int /*argc*/, char* /*argv*/[]) {
if (consecutive_predicts < max_consecutive_predicts) {
cv::Point2f temp_pred = kalman_tracker.predict();
if (temp_pred.x != 0 || temp_pred.y != 0) { // Check if prediction is valid
predicted_center = new cv::Point2f(temp_pred);
predicted_center = std::make_unique<cv::Point2f>(temp_pred);
}
} else {
predicted_center = nullptr;
@@ -169,13 +177,13 @@ int main(int /*argc*/, char* /*argv*/[]) {
// Determine display center
cv::Point2f* display_center = current_center;
if (display_center == nullptr && predicted_center != nullptr) {
display_center = predicted_center;
display_center = predicted_center.get();
}
bool is_predicted = (display_center != nullptr) && (current_center == nullptr);
// Calculate ballistic prediction point
cv::Point2f* ballistic_point = ballistic_predictor.predict_ballistic_point(
predicted_center, img_center, target_speed
predicted_center.get(), img_center, target_speed
);
auto current_time = std::chrono::high_resolution_clock::now();
@@ -210,24 +218,36 @@ int main(int /*argc*/, char* /*argv*/[]) {
std::this_thread::sleep_for(std::chrono::milliseconds(10 - elapsed));
}
// Clean up dynamically allocated memory
if (predicted_center != nullptr) {
delete predicted_center;
predicted_center = nullptr;
}
// Smart pointers automatically handle memory cleanup
}
}
catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
std::cerr << "Error in main loop: " << e.what() << std::endl;
}
catch (...) {
std::cerr << "Unknown error occurred in main loop" << std::endl;
}
// Cleanup
camera.release();
cv::destroyAllWindows();
try {
camera.release();
} catch (...) {
std::cerr << "Error during camera release" << std::endl;
}
try {
cv::destroyAllWindows();
} catch (...) {
std::cerr << "Error during window destruction" << std::endl;
}
// Only close TTL connection when enabled and initialized
if (use_ttl && ttl != nullptr) {
ttl->close();
try {
ttl->close();
} catch (...) {
std::cerr << "Error during TTL close" << std::endl;
}
delete ttl;
ttl = nullptr;
}