活动介绍

move std 函数 示例_std::enable_if

时间: 2023-06-29 19:20:15 浏览: 114
好的,这是一个关于 std::move 和 std::enable_if 的例子: ```c++ #include <iostream> #include <type_traits> template <typename T> typename std::enable_if<std::is_trivially_copyable<T>::value, void>::type swap(T& a, T& b) { std::cout << "using trivial swap\n"; T temp = std::move(a); a = std::move(b); b = std::move(temp); } template <typename T> typename std::enable_if<!std::is_trivially_copyable<T>::value, void>::type swap(T& a, T& b) { std::cout << "using non-trivial swap\n"; T temp(std::move(a)); a = std::move(b); b = std::move(temp); } int main() { int a = 1, b = 2; swap(a, b); std::cout << "a: " << a << ", b: " << b << std::endl; std::string s1 = "hello", s2 = "world"; swap(s1, s2); std::cout << "s1: " << s1 << ", s2: " << s2 << std::endl; return 0; } ``` 这是一个使用了 std::enable_if 的模板函数 swap,它可以根据模板参数的类型特性选择不同的实现。如果模板参数 T 是一个 trivially copyable 的类型,那么使用第一个实现;否则使用第二个实现。在其中,我们使用了 std::move 函数来实现对对象的移动操作,这可以避免不必要的拷贝操作,提高代码效率。
阅读全文

相关推荐

#include "dml-module.h" #include "cap.h" #include "cap_win.h" #include <nms.h> #include <opencv2/opencv.hpp> #include "AIMBOT.cpp" #include "mouse_controller.h" #include <windows.h> #include <chrono> #include <string> #include <filesystem> #include <iostream> #include <functional> #include <atomic> #include <mutex> #include <vector> #include <algorithm> #include <optional> #include "gbil_mouse_controller.h" #include "config.h" // ===== 新增:ADRC控制器结构体(自抗扰控制,解决动态目标扰动问题)===== struct ADRCController { float w0; // 观测器带宽 float b0; // 控制增益 float w_n; // 闭环带宽 float sigma; // 阻尼系数 float time_delta; // 时间步长(ms转换为秒) // 扩张状态观测器变量 float z1{ 0 }, z2{ 0 }, z3{ 0 }; // 状态观测值(位置、速度、扰动) float u_p{ 0 }; // 上一时刻控制量 std::mutex mtx; // 初始化ADRC参数(从配置文件读取) ADRCController(float w0_, float b0_, float w_n_, float sigma_, float dt) : w0(w0_), b0(b0_), w_n(w_n_), sigma(sigma_), time_delta(dt) { } // *核心方法:根据目标值和当前值计算补偿后的控制量 float update(float target, float current) { std::lock_guard<std::mutex> lock(mtx); float err = current - z1; // 跟踪误差 // 扩张状态观测器(ESO)更新 float fhan = this->fhan(err, z2, w_n, sigma); z1 += time_delta * (z2 + w0 * w0 * err); // 位置观测 z2 += time_delta * (z3 + 2 * w0 * z2 + w0 * w0 * fhan); // 速度观测 z3 += time_delta * (-3 * w0 * z3 + w0 * w0 * w0 * (current - z1)); // 扰动观测 // 控制律计算(补偿扰动) float u0 = w_n * w_n * (target - z1) - 2 * sigma * w_n * z2; float u = (u0 - z3) / b0; u_p = u; // 保存当前控制量 return u; } // 快速跟踪微分器(处理非线性特性) float fhan(float x1, float x2, float r, float h0) { float d = r * h0 * h0; float d0 = h0 * d; float y = x1 + h0 * x2; float a0 = sqrt(d * (d + 8 * abs(y))); float a; if (abs(y) > d0) { a = x2 + (a0 - d) / 2 * (y > 0 ? 1 : -1); } else { a = x2 + y / h0; } if (abs(a) > d) { return -r * (a > 0 ? 1 : -1); } else { return -r * a / d; } } void reset() { std::lock_guard<std::mutex> lock(mtx); z1 = z2 = z3 = 0; u_p = 0; } }; // ===== PID控制器结构体(保留原有功能,与ADRC级联)===== struct PIDController { float kp, ki, kd; float integral{ 0 }, last_error{ 0 }; std::mutex mtx; PIDController(float p, float i, float d) : kp(p), ki(i), kd(d) {} float compute(float error) { std::lock_guard<std::mutex> lock(mtx); integral += error; float derivative = error - last_error; last_error = error; return kp * error + ki * integral + kd * derivative; } void reset() { std::lock_guard<std::mutex> lock(mtx); integral = 0; last_error = 0; } }; // ===== 卡尔曼滤波类(参数可配置)===== class KalmanFilter { public: KalmanFilter(float process_noise, float obs_noise) { kf.init(4, 2, 0); kf.transitionMatrix = (cv::Mat_<float>(4, 4) << 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1); cv::setIdentity(kf.measurementMatrix); cv::setIdentity(kf.processNoiseCov, cv::Scalar::all(process_noise)); cv::setIdentity(kf.measurementNoiseCov, cv::Scalar::all(obs_noise)); cv::setIdentity(kf.errorCovPost, cv::Scalar::all(1)); } cv::Point2f predict(float x, float y) { cv::Mat measurement = (cv::Mat_<float>(2, 1) << x, y); kf.predict(); cv::Mat estimated = kf.correct(measurement); return cv::Point2f(estimated.at<float>(0), estimated.at<float>(1)); } private: cv::KalmanFilter kf; }; // ===== 新增:贝塞尔曲线生成工具(解决移动拖影,实现类人平滑路径)===== class BezierCurve { public: // 生成从起点到终点的贝塞尔曲线路径点 static std::vector<cv::Point2f> generatePoints( cv::Point2f start, cv::Point2f end, int num_points = 10) { // 路径点数量(越多越平滑)数值越大越慢 std::vector<cv::Point2f> points; // 生成随机内点(增加路径自然性) std::vector<cv::Point2f> control_points; control_points.push_back(start); // 添加2个随机内点(在起点和终点范围内) control_points.push_back(cv::Point2f( start.x + (end.x - start.x) * 0.3f + rand() % 5 - 2, // 微小随机偏移 start.y + (end.y - start.y) * 0.3f + rand() % 5 - 2 )); control_points.push_back(cv::Point2f( start.x + (end.x - start.x) * 0.7f + rand() % 5 - 2, start.y + (end.y - start.y) * 0.7f + rand() % 5 - 2 )); control_points.push_back(end); // 贝塞尔曲线采样 for (int i = 0; i < num_points; ++i) { float t = (float)i / (num_points - 1); points.push_back(bezier(t, control_points)); } return points; } private: // 贝塞尔曲线计算 static cv::Point2f bezier(float t, const std::vector<cv::Point2f>& points) { int n = points.size() - 1; cv::Point2f result(0, 0); for (int i = 0; i <= n; ++i) { float bernstein = binomial(n, i) * pow(t, i) * pow(1 - t, n - i); result.x += points[i].x * bernstein; result.y += points[i].y * bernstein; } return result; } // 二项式系数计算 static float binomial(int n, int k) { if (k < 0 || k > n) return 0; if (k == 0 || k == n) return 1; k = std::min(k, n - k); float res = 1; for (int i = 1; i <= k; ++i) { res = res * (n - k + i) / i; } return res; } }; // ===== 目标选择函数(安全封装)===== std::optional<Box> selectTarget( std::vector<Box>& filtered, int& tracked_id, int& tracking_counter, float anchor_x, float anchor_y, int width, int height ) { // 优先选择上次追踪目标 for (auto& box : filtered) { if (box.id == tracked_id) { tracking_counter++; return box; } } // 未找到则选择距离中心最近的目标 if (!filtered.empty()) { float min_dist = FLT_MAX; Box* best_target = nullptr; for (auto& box : filtered) { float cx = box.left + (box.right - box.left) * anchor_x; float cy = box.top + (box.bottom - box.top) * anchor_y; float dist = std::hypot(cx - width / 2.0f, cy - height / 2.0f); if (dist < min_dist) { min_dist = dist; best_target = &box; } } if (best_target) { tracked_id = best_target->id; tracking_counter = 1; return *best_target; } } return std::nullopt; } int main() { // ------ 新增:检查自身实例是否已在运行 开始 ------ // 通过创建全局命名互斥锁(Named Mutex)来判断是否已有一个实例在运行 HANDLE hInstanceMutex = CreateMutexW(nullptr, FALSE, L"Global\\GblidDemoVC_Mutex"); if (!hInstanceMutex || GetLastError() == ERROR_ALREADY_EXISTS) { MessageBoxW(NULL, L"请勿重复运行", L"提示", MB_OK | MB_ICONWARNING); if (hInstanceMutex) { CloseHandle(hInstanceMutex); } ExitProcess(0); // 已有实例,退出当前进程 } // ------ 新增:检查自身实例是否已在运行 结束 ------ // 隐藏控制台窗口 HWND consoleWindow = GetConsoleWindow(); // 获取当前控制台窗口句柄 ShowWindow(consoleWindow, SW_HIDE); // 隐藏控制台窗口(如果需要调试可以注释掉这行)//==========需要调试可以注释================== // ==== 加载配置 ==== Config config; if (!config.loadFromFile("./config.ini")) { printf("主程序-配置文件加载失败!\n"); return -1; } bool baim = (config.aim_part == 0); timeBeginPeriod(1); // 设置定时器精度为1ms // === 自动加载模型 === std::string model_dir = "onnx"; std::string model_path; for (const auto& entry : std::filesystem::directory_iterator(model_dir)) { if (entry.path().extension() == ".onnx") { model_path = entry.path().string(); break; } } if (model_path.empty()) { printf("主程序-未在 'onnx' 文件夹中找到任何 .onnx 模型文件!\n"); return -1; } printf("主程序-加载模型路径: %s\n", model_path.c_str()); // 初始化模型类 auto* frame = new IDML(); if (!frame->AnalyticalModel(model_path)) { printf("主程序-模型加载失败。\n"); return -2; } const auto& input_dims = frame->getInputDims(); if (input_dims.size() != 4) { printf("主程序-模型输入维度异常,当前维度数量: %llu\n", input_dims.size()); return -3; } int channels = static_cast<int>(input_dims[1]); int height = static_cast<int>(input_dims[2]); int width = static_cast<int>(input_dims[3]); printf("主程序-输入图像尺寸: %d x %d\n", width, height); // ==== 初始化控制器(*修改:新增ADRC控制器)==== PIDController pid_x(config.xkp, config.xki, config.xkd); PIDController pid_y(config.ykp, config.yki, config.ykd); // *ADRC参数(从配置文件读取,可根据动态目标特性调整) float adrc_dt = 0.016f; // 约60FPS的时间步长(1/60≈0.016s) ADRCController adrc_x(config.adrc_w0, config.adrc_b0, config.adrc_wn, config.adrc_sigma, adrc_dt); ADRCController adrc_y(config.adrc_w0, config.adrc_b0, config.adrc_wn, config.adrc_sigma, adrc_dt); KalmanFilter kf(config.kalman_Q, config.kalman_R); printf("主程序-控制参数: PID X[%.2f, %.3f, %.2f] Y[%.2f, %.3f, %.2f]\n", config.xkp, config.xki, config.xkd, config.ykp, config.yki, config.ykd); printf("主程序-ADRC参数: w0=%.1f, b0=%.2f, wn=%.1f, sigma=%.1f\n", config.adrc_w0, config.adrc_b0, config.adrc_wn, config.adrc_sigma); int screenW = GetSystemMetrics(SM_CXSCREEN); int screenH = GetSystemMetrics(SM_CYSCREEN); std::function<BYTE* ()> capture_func; void* cap_impl = nullptr; // 选择截图方式 if (config.screenshot_method == 0) { auto* c = new capture(screenW, screenH, width, height, "CrossFire"); cap_impl = c; capture_func = [c]() -> BYTE* { return (BYTE*)c->cap(); }; printf("主程序-截图方式: DXGI\n"); } else { auto* c = new capture_win32(screenW, screenH, width, height, "CrossFire"); cap_impl = c; capture_func = [c]() -> BYTE* { return c->cap(); }; printf("主程序-截图方式: Win32 BitBlt\n"); } // 初始化鼠标控制器 IMouseController* mouse = nullptr; if (config.move_type == 0) { mouse = new WinMouseController(); printf("主程序-使用鼠标控制器: WinMove\n"); } else if (config.move_type == 1) { mouse = new GBILMouseController(); printf("主程序-使用鼠标控制器: GBIL\n"); } else { printf("主程序-未知的 move_type 类型: %d,未启用鼠标移动!\n", config.move_type); } using Clock = std::chrono::high_resolution_clock; auto last_time = Clock::now(); float fps = 0.0f; // ==== 持续追踪状态 ==== static int tracked_id = -1; static int tracking_counter = 0; static int lost_counter = 0; // ==== 跟踪功能开关状态 ==== std::atomic<bool> tracking_enabled{ true }; bool last_tracking_toggle_state = false; bool last_exit_key_state = false; // ==== 新增:记录上一时刻鼠标位置(用于贝塞尔路径生成)==== cv::Point2f last_mouse_pos(0, 0); // ==== 主循环 ==== static bool target_locked = false; static int lock_frames_counter = 0; static float last_min_dist = FLT_MAX; while (true) { auto start = Clock::now(); // ==== 检查退出键 ==== bool current_exit_state = (GetAsyncKeyState(config.exit_key) & 0x8000) != 0; if (current_exit_state && !last_exit_key_state) { // 使用MB_SYSTEMMODAL标志使对话框置顶 [1,8](@ref) int result = MessageBoxA( NULL, "确定要退出YAK吗?", "退出确认", MB_OKCANCEL | MB_ICONQUESTION | MB_SYSTEMMODAL // 添加MB_SYSTEMMODAL标志 ); if (result == IDOK) { break; } } last_exit_key_state = current_exit_state; // ==== 检查跟踪开关键 ==== bool current_tracking_toggle = (GetAsyncKeyState(config.tracking_toggle_key) & 0x8000) != 0; if (current_tracking_toggle && !last_tracking_toggle_state) { tracking_enabled = !tracking_enabled; printf("主程序-跟踪功能已%s\n", tracking_enabled ? "开启" : "关闭"); } last_tracking_toggle_state = current_tracking_toggle; // 截图 BYTE* s = capture_func(); auto after_cap = Clock::now(); // 目标检测 float* data = frame->Detect(s); auto after_detect = Clock::now(); // 计算性能指标 float capture_ms = std::chrono::duration<float, std::milli>(after_cap - start).count(); float detect_ms = std::chrono::duration<float, std::milli>(after_detect - after_cap).count(); float frame_time = std::chrono::duration<float>(after_detect - last_time).count(); last_time = after_detect; fps = 1.0f / frame_time; std::vector<Box> oldbox; std::vector<Box> newbox = generate_yolo_proposals(data, oldbox, frame->out1, frame->out2, config.conf_threshold, config.nms_threshold); // ==== 目标过滤 ==== static std::vector<Box> filtered; filtered.clear(); for (auto& box : newbox) { if (config.valid_classes.empty() || std::find(config.valid_classes.begin(), config.valid_classes.end(), box.class_label) != config.valid_classes.end()) { filtered.push_back(box); } } // ==== 目标选择与锁定机制 ==== std::optional<Box> current_target = std::nullopt; if (tracking_enabled) { if (target_locked) { for (auto& box : filtered) { if (box.id == tracked_id) { current_target = box; tracking_counter++; lost_counter = 0; break; } } if (!current_target) { if (++lost_counter > 5) { target_locked = false; tracked_id = -1; tracking_counter = 0; lost_counter = 0; last_min_dist = FLT_MAX; } } } else if (!filtered.empty()) { float min_dist = FLT_MAX; Box* best_target = nullptr; for (auto& box : filtered) { float cx = box.left + (box.right - box.left) * config.anchor_x; float cy = box.top + (box.bottom - box.top) * config.anchor_y; float dist = std::hypot(cx - width / 2.0f, cy - height / 2.0f); if (dist < min_dist && (tracked_id == -1 || dist < last_min_dist * 0.8f)) { min_dist = dist; best_target = &box; } } if (best_target) { current_target = *best_target; tracked_id = best_target->id; tracking_counter = 1; last_min_dist = min_dist; if (min_dist < config.lock_threshold) { if (++lock_frames_counter >= config.lock_frames) { target_locked = true; lock_frames_counter = 0; } } else { lock_frames_counter = 0; } } } } // ==== 鼠标控制逻辑(*核心修改:PID+ADRC级联控制+贝塞尔路径平滑)==== bool aim_key_pressed = (GetAsyncKeyState(config.aim_key) & 0x8000) != 0; bool aim_key1_pressed = (GetAsyncKeyState(config.aim_key1) & 0x8000) != 0; bool any_aim_key_pressed = aim_key_pressed || aim_key1_pressed; if (any_aim_key_pressed && mouse && tracking_enabled) { if (current_target) { // 计算锚点位置 float center_x = current_target->left + (current_target->right - current_target->left) * config.anchor_x; float center_y = current_target->top + (current_target->bottom - current_target->top) * config.anchor_y; cv::Point2f smoothed; if (config.kalman_enable) { smoothed = kf.predict(center_x, center_y); } else { smoothed = cv::Point2f(center_x, center_y); } // 计算原始偏移(目标与屏幕中心的偏差) float raw_dx = smoothed.x - width / 2.0f; float raw_dy = smoothed.y - height / 2.0f; // *步骤1:PID计算基础移动量(比例+积分+微分) float pid_dx = pid_x.compute(raw_dx); float pid_dy = pid_y.compute(raw_dy); // *步骤2:ADRC补偿动态扰动(解决动态目标跟踪延迟) float adrc_dx = adrc_x.update(pid_dx, raw_dx); // 输入PID输出和原始偏差 float adrc_dy = adrc_y.update(pid_dy, raw_dy); // *步骤3:贝塞尔曲线生成平滑路径(解决移动拖影) cv::Point2f target_pos(last_mouse_pos.x + adrc_dx, last_mouse_pos.y + adrc_dy); std::vector<cv::Point2f> path = BezierCurve::generatePoints(last_mouse_pos, target_pos); // *步骤4:按平滑路径移动鼠标 for (const auto& p : path) { mouse->updateTarget(p.x - last_mouse_pos.x, p.y - last_mouse_pos.y); last_mouse_pos = p; // 更新当前鼠标位置 Sleep(1); // 微小延迟,确保平滑效果 } } else { // 无目标时重置 mouse->updateTarget(0.0f, 0.0f); pid_x.reset(); pid_y.reset(); adrc_x.reset(); // *重置ADRC adrc_y.reset(); last_mouse_pos = cv::Point2f(0, 0); target_locked = false; tracked_id = -1; lock_frames_counter = 0; } } else { // 未按触发键时重置 if (mouse) mouse->updateTarget(0.0f, 0.0f); target_locked = false; tracked_id = -1; tracking_counter = 0; lock_frames_counter = 0; pid_x.reset(); pid_y.reset(); adrc_x.reset(); // *重置ADRC adrc_y.reset(); last_mouse_pos = cv::Point2f(0, 0); } // ==== 调试窗口显示 ==== if (config.show_window) { cv::Mat a(height, width, CV_8UC3, s); if (!newbox.empty()) { for (const Box& detection : newbox) { cv::Scalar color = (current_target && detection.id == current_target->id) ? cv::Scalar(0, 0, 255) : cv::Scalar(0, 255, 0); int thickness = (current_target && detection.id == current_target->id) ? 2 : 1; cv::rectangle(a, cv::Point((int)detection.left, (int)detection.top), cv::Point((int)detection.right, (int)detection.bottom), color, thickness ); std::string class_str = std::to_string(detection.class_label); char conf_str[16]; snprintf(conf_str, sizeof(conf_str), "%.2f", detection.confidence); int fontFace = cv::FONT_HERSHEY_SIMPLEX; double fontScale = 0.4; int textThickness = 1; cv::Point textOrg((int)detection.left, (int)detection.top - 4); if (textOrg.y < 10) textOrg.y = 10; cv::putText(a, class_str, textOrg, fontFace, fontScale, cv::Scalar(0, 0, 255), textThickness); cv::Size textSize = cv::getTextSize(class_str, fontFace, fontScale, textThickness, nullptr); cv::Point confOrg = textOrg + cv::Point(textSize.width + 4, 0); cv::putText(a, conf_str, confOrg, fontFace, fontScale, cv::Scalar(0, 255, 0), textThickness); } } // 绘制锚点和追踪线 if (current_target && any_aim_key_pressed && tracking_enabled) { int anchor_x_pos = current_target->left + (current_target->right - current_target->left) * config.anchor_x; int anchor_y_pos = current_target->top + (current_target->bottom - current_target->top) * config.anchor_y; cv::circle(a, cv::Point(anchor_x_pos, anchor_y_pos), 5, cv::Scalar(255, 0, 255), -1); cv::line(a, cv::Point(width / 2, height / 2), cv::Point(anchor_x_pos, anchor_y_pos), cv::Scalar(0, 255, 255), 1); } // 性能指标显示 int base_y = 20; int line_height = 18; double font_scale = 0.5; int thickness = 1; auto draw_metric = [&](const std::string& label, const std::string& value, int line) { int y = base_y + line * line_height; cv::putText(a, label, cv::Point(10, y), cv::FONT_HERSHEY_SIMPLEX, font_scale, cv::Scalar(0, 0, 255), thickness); cv::putText(a, value, cv::Point(80, y), cv::FONT_HERSHEY_SIMPLEX, font_scale, cv::Scalar(0, 255, 0), thickness); }; draw_metric("FPS:", std::to_string((int)fps), 0); draw_metric("CAPTURE:", std::to_string((int)capture_ms) + "ms", 1); draw_metric("DETECT:", std::to_string((int)detect_ms) + "ms", 2); draw_metric("TRACK:", tracking_enabled ? "ON" : "OFF", 3); // 状态信息显示 if (current_target) { std::string track_info = "TRACK: " + std::to_string(tracking_counter); cv::putText(a, track_info, cv::Point(width - 120, 30), cv::FONT_HERSHEY_SIMPLEX, 0.6, cv::Scalar(200, 200, 0), 1); } if (target_locked) { std::string lock_info = "LOCKED: " + std::to_string(tracked_id); cv::putText(a, lock_info, cv::Point(width - 120, 60), cv::FONT_HERSHEY_SIMPLEX, 0.6, cv::Scalar(0, 200, 255), 1); } if (lost_counter > 0) { std::string lost_info = "LOST: " + std::to_string(lost_counter); cv::putText(a, lost_info, cv::Point(width - 120, 90), cv::FONT_HERSHEY_SIMPLEX, 0.6, cv::Scalar(0, 200, 200), 1); } // 窗口置顶设置 static bool topmost_set = false; if (!topmost_set) { HWND hwnd = FindWindowA(NULL, "c"); if (hwnd) { SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); } topmost_set = true; } cv::imshow("c", a); cv::waitKey(1); } } // 退出前释放资源 if (mouse) { mouse->stop(); delete mouse; mouse = nullptr; } delete frame; if (cap_impl) { if (config.screenshot_method == 0) { delete static_cast<capture*>(cap_impl); } else { delete static_cast<capture_win32*>(cap_impl); } } timeEndPeriod(1); return 0; }这个是c++程序,你帮忙分析一下,为什么跟踪目标会跟不上,还会有拖影

#pragma once #include <vector> #include <string> class Config { public: Config(); bool loadFromFile(const std::string& filePath); // === 可视化 & 推理阈值 === int show_window; // 窗口显示开关 (0=不显示,1=显示) float conf_threshold; // 检测置信度阈值 [0.0,1.0] float nms_threshold; // NMS 重叠阈值 [0.0,1.0] // === 瞄准 & FOV === int aim_part; // 瞄准部位 (0=头,1=胸 等) float xfov, yfov; // 水平 / 垂直 视野因子 // === 截图方式 === int screenshot_method; // 0=DXGI, 1=Win32 BitBlt // === 卡尔曼滤波参数 === float kalman_Q; // 过程噪声协方差 float kalman_R; // 测量噪声协方差 int kalman_enable; // 0=禁用,1=启用 // === 鼠标控制参数 === int move_type; // 0=WinMove,1=GBIL 等 int aim_key; // 触发键1 (VK code) int aim_key1; // 触发键2 (VK code) int tracking_toggle_key; // 跟踪开启/关闭键 (VK code) int exit_key; // 退出程序键 (VK code) // === 单目标追踪锁定参数 === float lock_threshold; // 距离中心锁定阈值 (像素) int lock_frames; // 锁定前需持续多少帧 // === 平滑 (PID) 参数 === float xkp, xki, xkd; // X 方向 PID 三项系数 float ykp, yki, ykd; // Y 方向 PID 三项系数 // === 类别过滤 === std::vector<int> valid_classes; // 可跟踪类别列表 // === 锚点偏移比 === float anchor_x; // 框内 X 方向锚点比例 [0.0,1.0] float anchor_y; // 框内 Y 方向锚点比例 [0.0,1.0] // === 多目标跟踪 (MOT) 关联参数 === float iou_threshold; // IOU 关联阈值 [0.0,1.0] int max_lost_frames; // Track 丢失后允许的最大未匹配帧数 int min_hits; // Track 在被认为“有效”前需连续命中帧数 // === 预测系统参数 === int prediction_enable; // 0=禁用, 1=启用 float prediction_coefficient; // 预测系数 int prediction_history_size; // 历史记录数量 int system_delay; // 系统延迟(毫秒) float min_velocity_threshold; // 最小速度阈值 // === ADRC控制器参数(新增) === float adrc_w0; // 观测器带宽 float adrc_b0; // 控制增益 float adrc_wn; // 闭环带宽 float adrc_sigma; // 阻尼系数 };config.h代码和 #include "config.h" #include <windows.h> #include <cstring> Config::Config() { // ---- 默认值 ---- show_window = 1; conf_threshold = 0.4f; nms_threshold = 0.5f; aim_part = 1; xfov = 1.0f; yfov = 1.33f; screenshot_method = 0; kalman_Q = 0.0001f; kalman_R = 10.0f; kalman_enable = 1; move_type = 0; aim_key = 0x10; // Shift aim_key1 = 0x02; // 鼠标右键 tracking_toggle_key = 0x24; // Home exit_key = 0x23; // End lock_threshold = 50.0f; lock_frames = 5; xkp = 0.8f; xki = 0.005f; xkd = 0.15f; ykp = 0.8f; yki = 0.005f; ykd = 0.15f; anchor_x = 0.5f; anchor_y = 0.5f; // MOT 新增部分 iou_threshold = 0.3f; max_lost_frames = 5; min_hits = 3; // 预测系统默认值 prediction_enable = 1; prediction_coefficient = 0.8f; prediction_history_size = 10; system_delay = 50; min_velocity_threshold = 50.0f; // === ADRC默认参数(新增) === adrc_w0 = 50.0f; // 观测器带宽 adrc_b0 = 0.8f; // 控制增益 adrc_wn = 50.0f; // 闭环带宽 adrc_sigma = 1.0f; // 阻尼系数 } bool Config::loadFromFile(const std::string& filePath) { // ---- WINDOWS ---- show_window = GetPrivateProfileIntA("WINDOWS", "show_windows", show_window, filePath.c_str()); // ---- PRED ---- conf_threshold = GetPrivateProfileIntA("PRED", "conf_threshold", static_cast<int>(conf_threshold * 100), filePath.c_str()) / 100.0f; nms_threshold = GetPrivateProfileIntA("PRED", "nms_threshold", static_cast<int>(nms_threshold * 100), filePath.c_str()) / 100.0f; aim_part = GetPrivateProfileIntA("PRED", "aim_part", aim_part, filePath.c_str()); xfov = GetPrivateProfileIntA("PRED", "xfov", static_cast<int>(xfov * 100), filePath.c_str()) / 100.0f; yfov = GetPrivateProfileIntA("PRED", "yfov", static_cast<int>(yfov * 100), filePath.c_str()) / 100.0f; screenshot_method = GetPrivateProfileIntA("PRED", "Screenshot_method", screenshot_method, filePath.c_str()); // ---- 锚点 ---- anchor_x = GetPrivateProfileIntA("PRED", "anchor_x", static_cast<int>(anchor_x * 100), filePath.c_str()) / 100.0f; anchor_y = GetPrivateProfileIntA("PRED", "anchor_y", static_cast<int>(anchor_y * 100), filePath.c_str()) / 100.0f; // ---- 类别过滤 ---- valid_classes.clear(); { char buffer[256]; GetPrivateProfileStringA("PRED", "track_class", "", buffer, sizeof(buffer), filePath.c_str()); char* next = nullptr; char* token = strtok_s(buffer, ",", &next); while (token) { valid_classes.push_back(std::atoi(token)); token = strtok_s(nullptr, ",", &next); } } // ---- KALMAN ---- kalman_Q = GetPrivateProfileIntA("KALMAN", "process_noise", static_cast<int>(kalman_Q * 1e6), filePath.c_str()) / 1e6f; kalman_R = GetPrivateProfileIntA("KALMAN", "obs_noise", static_cast<int>(kalman_R * 100), filePath.c_str()) / 100.0f; kalman_enable = GetPrivateProfileIntA("KALMAN", "enable", kalman_enable, filePath.c_str()); // ---- MOUSE & CONTROL ---- move_type = GetPrivateProfileIntA("MOUSE", "move_type", move_type, filePath.c_str()); aim_key = GetPrivateProfileIntA("CONTROL", "aim_key", aim_key, filePath.c_str()); aim_key1 = GetPrivateProfileIntA("CONTROL", "aim_key1", aim_key1, filePath.c_str()); tracking_toggle_key = GetPrivateProfileIntA("CONTROL", "tracking_toggle_key", tracking_toggle_key, filePath.c_str()); exit_key = GetPrivateProfileIntA("CONTROL", "exit_key", exit_key, filePath.c_str()); // ---- TRACK (单目标) ---- lock_threshold = static_cast<float>(GetPrivateProfileIntA("TRACK", "lock_threshold", static_cast<int>(lock_threshold), filePath.c_str())); lock_frames = GetPrivateProfileIntA("TRACK", "lock_frames", lock_frames, filePath.c_str()); // ---- SMOOTH (PID) ---- xkp = GetPrivateProfileIntA("SMOOTH", "xkp", static_cast<int>(xkp * 100), filePath.c_str()) / 100.0f; xki = GetPrivateProfileIntA("SMOOTH", "xki", static_cast<int>(xki * 1000), filePath.c_str()) / 1000.0f; xkd = GetPrivateProfileIntA("SMOOTH", "xkd", static_cast<int>(xkd * 100), filePath.c_str()) / 100.0f; ykp = GetPrivateProfileIntA("SMOOTH", "ykp", static_cast<int>(ykp * 100), filePath.c_str()) / 100.0f; yki = GetPrivateProfileIntA("SMOOTH", "yki", static_cast<int>(yki * 1000), filePath.c_str()) / 1000.0f; ykd = GetPrivateProfileIntA("SMOOTH", "ykd", static_cast<int>(ykd * 100), filePath.c_str()) / 100.0f; // ---- 预测系统参数 ---- prediction_enable = GetPrivateProfileIntA("PREDICTION", "prediction_enable", prediction_enable, filePath.c_str()); prediction_coefficient = GetPrivateProfileIntA("PREDICTION", "prediction_coefficient", static_cast<int>(prediction_coefficient * 100), filePath.c_str()) / 100.0f; prediction_history_size = GetPrivateProfileIntA("PREDICTION", "prediction_history_size", prediction_history_size, filePath.c_str()); system_delay = GetPrivateProfileIntA("PREDICTION", "system_delay", system_delay, filePath.c_str()); min_velocity_threshold = static_cast<float>(GetPrivateProfileIntA("PREDICTION", "min_velocity_threshold", static_cast<int>(min_velocity_threshold), filePath.c_str())); // ---- MOT 关联配置 ---- iou_threshold = GetPrivateProfileIntA("MOT", "iou_threshold", static_cast<int>(iou_threshold * 100), filePath.c_str()) / 100.0f; max_lost_frames = GetPrivateProfileIntA("MOT", "max_lost_frames", max_lost_frames, filePath.c_str()); min_hits = GetPrivateProfileIntA("MOT", "min_hits", min_hits, filePath.c_str()); // === ADRC参数加载(修改后) === char buffer[32]; if (GetPrivateProfileStringA("ADRC", "w0", "", buffer, sizeof(buffer), filePath.c_str())) { adrc_w0 = std::stof(buffer); } if (GetPrivateProfileStringA("ADRC", "b0", "", buffer, sizeof(buffer), filePath.c_str())) { adrc_b0 = std::stof(buffer); } if (GetPrivateProfileStringA("ADRC", "wn", "", buffer, sizeof(buffer), filePath.c_str())) { adrc_wn = std::stof(buffer); } if (GetPrivateProfileStringA("ADRC", "sigma", "", buffer, sizeof(buffer), filePath.c_str())) { adrc_sigma = std::stof(buffer); } // 打印ADRC参数加载结果 printf("配置文件读取-ADRC参数: w0=%.1f, b0=%.2f, wn=%.1f, sigma=%.1f\n", adrc_w0, adrc_b0, adrc_wn, adrc_sigma); return true; }config.cpp代码,把修改后的完整代码发我 因为主程序的 // ==== 初始化控制器 ==== PIDController pid_x(config.xkp, config.xki, config.xkd); PIDController pid_y(config.ykp, config.yki, config.ykd); // ===== 新增:滑模控制器(解决动态目标跟踪延迟)===== SlidingModeController smc_x(config.smc_k, config.smc_lambda, config.smc_epsilon); SlidingModeController smc_y(config.smc_k, config.smc_lambda, config.smc_epsilon); // ===== 新增:轨迹管理器(解决目标丢失拖影)===== TrajectoryManager trajectory_mgr(config.max_misses, config.decay_factor); KalmanFilter kf(config.kalman_Q, config.kalman_R); printf("主程序-控制参数: PID X[%.2f, %.3f, %.2f] Y[%.2f, %.3f, %.2f]\n", config.xkp, config.xki, config.xkd, config.ykp, config.yki, config.ykd); printf("主程序-滑模参数: k=%.1f, λ=%.1f, ε=%.2f\n", config.smc_k, config.smc_lambda, config.smc_epsilon);和 // 应用移动(带平滑处理) mouse->updateTarget(final_dx * config.sensitivity, final_dy * config.sensitivity);报凑

最新推荐

recommend-type

MATLAB常用函数说明(1).doc

MATLAB常用函数说明(1).doc
recommend-type

电子商务下的物流仓储管理教材(1).pptx

电子商务下的物流仓储管理教材(1).pptx
recommend-type

精选Java案例开发技巧集锦

从提供的文件信息中,我们可以看出,这是一份关于Java案例开发的集合。虽然没有具体的文件名称列表内容,但根据标题和描述,我们可以推断出这是一份包含了多个Java编程案例的开发集锦。下面我将详细说明与Java案例开发相关的一些知识点。 首先,Java案例开发涉及的知识点相当广泛,它不仅包括了Java语言的基础知识,还包括了面向对象编程思想、数据结构、算法、软件工程原理、设计模式以及特定的开发工具和环境等。 ### Java基础知识 - **Java语言特性**:Java是一种面向对象、解释执行、健壮性、安全性、平台无关性的高级编程语言。 - **数据类型**:Java中的数据类型包括基本数据类型(int、short、long、byte、float、double、boolean、char)和引用数据类型(类、接口、数组)。 - **控制结构**:包括if、else、switch、for、while、do-while等条件和循环控制结构。 - **数组和字符串**:Java数组的定义、初始化和多维数组的使用;字符串的创建、处理和String类的常用方法。 - **异常处理**:try、catch、finally以及throw和throws的使用,用以处理程序中的异常情况。 - **类和对象**:类的定义、对象的创建和使用,以及对象之间的交互。 - **继承和多态**:通过extends关键字实现类的继承,以及通过抽象类和接口实现多态。 ### 面向对象编程 - **封装、继承、多态**:是面向对象编程(OOP)的三大特征,也是Java编程中实现代码复用和模块化的主要手段。 - **抽象类和接口**:抽象类和接口的定义和使用,以及它们在实现多态中的不同应用场景。 ### Java高级特性 - **集合框架**:List、Set、Map等集合类的使用,以及迭代器和比较器的使用。 - **泛型编程**:泛型类、接口和方法的定义和使用,以及类型擦除和通配符的应用。 - **多线程和并发**:创建和管理线程的方法,synchronized和volatile关键字的使用,以及并发包中的类如Executor和ConcurrentMap的应用。 - **I/O流**:文件I/O、字节流、字符流、缓冲流、对象序列化的使用和原理。 - **网络编程**:基于Socket编程,使用java.net包下的类进行网络通信。 - **Java内存模型**:理解堆、栈、方法区等内存区域的作用以及垃圾回收机制。 ### Java开发工具和环境 - **集成开发环境(IDE)**:如Eclipse、IntelliJ IDEA等,它们提供了代码编辑、编译、调试等功能。 - **构建工具**:如Maven和Gradle,它们用于项目构建、依赖管理以及自动化构建过程。 - **版本控制工具**:如Git和SVN,用于代码的版本控制和团队协作。 ### 设计模式和软件工程原理 - **设计模式**:如单例、工厂、策略、观察者、装饰者等设计模式,在Java开发中如何应用这些模式来提高代码的可维护性和可扩展性。 - **软件工程原理**:包括软件开发流程、项目管理、代码审查、单元测试等。 ### 实际案例开发 - **项目结构和构建**:了解如何组织Java项目文件,合理使用包和模块化结构。 - **需求分析和设计**:明确项目需求,进行系统设计,如数据库设计、系统架构设计等。 - **代码编写和实现**:根据设计编写符合要求的代码,实现系统的各个模块功能。 - **测试和维护**:进行单元测试、集成测试,确保代码质量,对项目进行维护和升级。 ### 其他相关知识点 - **Java虚拟机(JVM)**:了解JVM的基本工作原理,包括类加载机制、内存管理、垃圾回收算法等。 - **常用Java框架**:比如Spring、Hibernate、MyBatis等,在实际开发中常常与Java基础结合使用,提高开发效率。 以上知识点可以作为学习Java案例开发的基础框架。在实际的开发实践中,开发者需要结合具体的项目需求,对这些知识点进行灵活运用。通过反复的案例实践,可以加深对Java编程的理解,并逐步提升开发技能。这份集锦可能包含的案例可能涉及上述知识点的具体应用,能够帮助学习者更好地理解理论与实践的结合,从而快速提升个人的Java开发能力。
recommend-type

【VASP报错深度解析】:5大技巧识别并永久解决离子距离太近警告

# 1. VASP软件简介及离子距离太近问题概述 ## 1.1 VASP软件简介 **VASP(Vienna Ab initio Simulation Package)** 是一款广泛应用于计算材料科学的软件,它基于密度泛函理论(DFT)计算固体、表面和分子的电子结构和性质。
recommend-type

npm error A complete log of this run can be found in: D:\Program Files\nodejs\node_cache\_logs\2025-04-20T15_11_51_454Z-debug-0.log

<think>好的,我需要帮助用户找到npm的错误调试日志位置,并解决他们遇到的npm错误。首先,用户已经提供了一个具体的日志路径:'D:\Program Files\nodejs\node_cache\_logs\2025-04-20T15_11_51_454Z-debug-0.log',但看起来这个路径可能有问题,因为日期是2025年,这可能是一个示例或输入错误。我需要确认正确的日志路径生成方式。 根据npm的默认配置,日志文件通常位于npm的缓存目录下的_logs文件夹中。默认情况下,Windows系统中npm的缓存路径是%AppData%\npm-cache,而日志文件会以当前日期和
recommend-type

深入理解内存技术文档详解

由于文件内容无法查看,仅能根据文件的标题、描述、标签以及文件名称列表来构建相关知识点。以下是对“内存详解”这一主题的详细知识点梳理。 内存,作为计算机硬件的重要组成部分,负责临时存放CPU处理的数据和指令。理解内存的工作原理、类型、性能参数等对优化计算机系统性能至关重要。本知识点将从以下几个方面来详细介绍内存: 1. 内存基础概念 内存(Random Access Memory,RAM)是易失性存储器,这意味着一旦断电,存储在其中的数据将会丢失。内存允许计算机临时存储正在执行的程序和数据,以便CPU可以快速访问这些信息。 2. 内存类型 - 动态随机存取存储器(DRAM):目前最常见的RAM类型,用于大多数个人电脑和服务器。 - 静态随机存取存储器(SRAM):速度较快,通常用作CPU缓存。 - 同步动态随机存取存储器(SDRAM):在时钟信号的同步下工作的DRAM。 - 双倍数据速率同步动态随机存取存储器(DDR SDRAM):在时钟周期的上升沿和下降沿传输数据,大幅提升了内存的传输速率。 3. 内存组成结构 - 存储单元:由存储位构成的最小数据存储单位。 - 地址总线:用于选择内存中的存储单元。 - 数据总线:用于传输数据。 - 控制总线:用于传输控制信号。 4. 内存性能参数 - 存储容量:通常用MB(兆字节)或GB(吉字节)表示,指的是内存能够存储多少数据。 - 内存时序:指的是内存从接受到请求到开始读取数据之间的时间间隔。 - 内存频率:通常以MHz或GHz为单位,是内存传输数据的速度。 - 内存带宽:数据传输速率,通常以字节/秒为单位,直接关联到内存频率和数据位宽。 5. 内存工作原理 内存基于电容器和晶体管的工作原理,电容器存储电荷来表示1或0的状态,晶体管则用于读取或写入数据。为了保持数据不丢失,动态内存需要定期刷新。 6. 内存插槽与安装 - 计算机主板上有专用的内存插槽,常见的有DDR2、DDR3、DDR4和DDR5等不同类型。 - 安装内存时需确保兼容性,并按照正确的方向插入内存条,避免物理损坏。 7. 内存测试与优化 - 测试:可以使用如MemTest86等工具测试内存的稳定性和故障。 - 优化:通过超频来提高内存频率,但必须确保稳定性,否则会导致数据损坏或系统崩溃。 8. 内存兼容性问题 不同内存条可能由于制造商、工作频率、时序、电压等参数的不匹配而产生兼容性问题。在升级或更换内存时,必须检查其与主板和现有系统的兼容性。 9. 内存条的常见品牌与型号 诸如金士顿(Kingston)、海盗船(Corsair)、三星(Samsung)和芝奇(G.Skill)等知名品牌提供多种型号的内存条,针对不同需求的用户。 由于“内存详解.doc”是文件标题指定的文件内容,我们可以预期在该文档中将详细涵盖以上知识点,并有可能包含更多的实践案例、故障排查方法以及内存技术的最新发展等高级内容。在实际工作中,理解并应用这些内存相关的知识点对于提高计算机性能、解决计算机故障有着不可估量的价值。
recommend-type

【机械特性分析进阶秘籍】:频域与时域对比的全面研究

# 1. 机械特性分析的频域与时域概述 ## 1.1 频域与时域分析的基本概念 机械特性分析是通
recommend-type

dslicsrv安装报错Too many errors

<think>好的,用户遇到了安装dslicsrv时出现“Too many errors”的问题,需要帮助解决。首先,我需要明确dslicsrv是什么。可能是指某个特定的软件服务,但根据常见软件库和搜索引擎的信息,没有直接对应的结果。可能是拼写错误,或者是某个特定领域的专有软件?比如,可能与Dell的某个服务有关?例如,Dell System License Manager Service(dsLicSvc)可能更接近。假设用户可能拼写错误,将dslicsrv理解为dsLicSvc,即Dell的系统许可证管理服务。 接下来,用户遇到的错误是安装时出现“Too many errors”,这通常
recommend-type

深入解析Pro Ajax与Java技术的综合应用框架

根据提供的文件信息,我们可以推断出一系列与标题《Pro Ajax and Java》相关的IT知识点。这本书是由Apress出版,关注的是Ajax和Java技术。下面我将详细介绍这些知识点。 ### Ajax技术 Ajax(Asynchronous JavaScript and XML)是一种无需重新加载整个页面即可更新网页的技术。它通过在后台与服务器进行少量数据交换,实现了异步更新网页内容的目的。 1. **异步通信**:Ajax的核心是通过XMLHttpRequest对象或者现代的Fetch API等技术实现浏览器与服务器的异步通信。 2. **DOM操作**:利用JavaScript操作文档对象模型(DOM),能够实现页面内容的动态更新,而无需重新加载整个页面。 3. **数据交换格式**:Ajax通信中常使用的数据格式包括XML和JSON,但近年来JSON因其轻量级和易用性更受青睐。 4. **跨浏览器兼容性**:由于历史原因,实现Ajax的JavaScript代码需要考虑不同浏览器的兼容性问题。 5. **框架和库**:有许多流行的JavaScript库和框架支持Ajax开发,如jQuery、Dojo、ExtJS等,这些工具简化了Ajax的实现和数据操作。 ### Java技术 Java是一种广泛使用的面向对象编程语言,其在企业级应用、移动应用开发(Android)、Web应用开发等方面有着广泛应用。 1. **Java虚拟机(JVM)**:Java程序运行在Java虚拟机上,这使得Java具有良好的跨平台性。 2. **Java标准版(Java SE)**:包含了Java的核心类库和API,是Java应用开发的基础。 3. **Java企业版(Java EE)**:为企业级应用提供了额外的API和服务,如Java Servlet、JavaServer Pages(JSP)、Enterprise JavaBeans(EJB)等。 4. **面向对象编程(OOP)**:Java是一种纯粹的面向对象语言,它的语法和机制支持封装、继承和多态性。 5. **社区和生态系统**:Java拥有庞大的开发者社区和丰富的第三方库和框架,如Spring、Hibernate等,这些资源极大丰富了Java的应用范围。 ### 结合Ajax和Java 在结合使用Ajax和Java进行开发时,我们通常会采用MVC(模型-视图-控制器)架构模式,来构建可维护和可扩展的应用程序。 1. **服务器端技术**:Java经常被用来构建服务器端应用逻辑。例如,使用Servlet来处理客户端的请求,再将数据以Ajax请求的响应形式返回给客户端。 2. **客户端技术**:客户端的JavaScript(或使用框架库如jQuery)用于发起Ajax请求,并更新页面内容。 3. **数据格式**:Java后端通常会使用JSON或XML格式与Ajax进行数据交换。 4. **安全性**:Ajax请求可能涉及敏感数据,因此需要考虑如跨站请求伪造(CSRF)等安全问题。 5. **性能优化**:合理使用Ajax可以提升用户体验,但同时也需要注意对服务器和网络的负载,以及客户端脚本的执行性能。 ### 出版信息及文件信息 《Pro Ajax and Java》由Apress出版社出版,通常这种出版物会包含丰富的实例代码、开发指导、最佳实践以及相关的技术讨论。它旨在帮助开发者深化对Ajax和Java技术的理解和应用能力。 文件名“Apress.Pro.Ajax.and.Java.Frameworks.Jul.2006.HAPPY.NEW.YEAR.pdf”暗示了这份文档可能是一本专业的技术书籍。从文件名可以看出,该书还可能包含了框架使用方面的内容,并且是2006年出版的。标题中的“HAPPY.NEW.YEAR”可能仅仅是为了庆祝新年而加入的非标准部分。 总结而言,了解Ajax和Java的结合使用,不仅需要掌握两种技术的基本原理和使用方法,还要熟悉如何将它们整合到实际项目中,解决可能出现的技术挑战,从而构建功能强大且用户友好的Web应用。
recommend-type

【频域分析深度解读】:揭秘机械系统分析中的实用应用

# 1. 频域分析基础理论 频域分析是信号处理领域的一个重要分支,其核心在于研究信号在频率维度上的特性。与时域分析不同,频域分析关注的是信号频率成分的组成,这允许我们以一种直观的方式识别和处理信号中的特定频率特征。通过对信号进行傅里叶变换,原始的时域信号可以被转换为频域信号,这样就可以清晰地显示出各频率成分的幅度和相位信息。这种分析手段对于信号去噪、特征提取、压缩编码等应用场景至关重