全局结构图
struct SteerQueue {
std::queue<float> queue; // 存储舵机角度值的队列
std::mutex mtx; // 互斥锁保护队列
std::condition_variable cv; // 条件变量用于线程同步
volatile bool stop_flag = false; // 线程停止标志
};
SteerQueue steer_queue;
# 🔹 std::queue<float> queue;
- 作用:存储即将发送给舵机的角度值(如 65°、75°、85°)。
- 典型流程:图像线程计算完角度后调用
steer_queue.queue.push(angle);舵机线程再从中读取queue.front()执行控制。
# 🔹 std::mutex mtx;
-
作用:互斥锁,用于保护队列的读写,防止两个线程同时访问导致“数据竞争”或程序崩溃。
-
使用方式:
std::lock_guard<std::mutex> lock(steer_queue.mtx); steer_queue.queue.push(angle);
# 🔹 std::condition_variable cv;
-
作用:条件变量,用于通知舵机线程有新角度可以处理,否则舵机线程就一直阻塞、等待。
-
工作流程:
-
图像线程调用
cv.notify_one();通知舵机线程。 -
舵机线程使用
cv.wait(lock, 条件)挂起等待新值。
-
# 🔹 volatile bool stop_flag = false;
-
作用:控制舵机线程的停止条件。
-
volatile关键词含义:告诉编译器这个变量可能会被其他线程修改,不要对它进行优化缓存,确保读取的是最新值。 -
使用方式:当主程序要退出时设置
stop_flag = true;,舵机线程检测后退出循环:if (steer_queue.stop_flag) break;
- 图像线程:负责分析图像并“投递”角度值;
- 舵机线程:负责从队列中取出角度值并控制舵机;
- 互斥锁 & 条件变量:确保线程之间安全地读写队列;
- 停止标志:支持程序优雅地退出。
// 舵机控制线程函数
void steeringThread() {
// 循环直到收到停止信号
while (!steer_queue.stop_flag) {
std::unique_lock<std::mutex> lock(steer_queue.mtx);
// 等待条件:队列非空或停止标志置位
steer_queue.cv.wait(lock, []{
return !steer_queue.queue.empty() || steer_queue.stop_flag;
});
// 检查退出条件
if (steer_queue.stop_flag && steer_queue.queue.empty()) break;
if (!steer_queue.queue.empty()) {
// 优化策略:跳过所有积压指令,只处理最新角度
float angle;
while (!steer_queue.queue.empty()) {
angle = steer_queue.queue.front(); // 获取队首
steer_queue.queue.pop(); // 移除指令
}
lock.unlock(); // 提前释放锁,减少临界区时间
// 调试输出(实际使用时可能注释掉)
// printf("Steer_Angle = %d\n", static_cast<int>(angle));
// 更新舵机PWM信号:将角度转换为占空比值
update_duty(0, angle_to_duty(angle));
// 控制舵机更新频率(200ms/5Hz)
usleep(200000); // 200毫秒延时
}
}
}

