项目结构大变
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user