1、項目簡介
在本次項目中,我們將采用LockAI視覺攝像頭與OpenCV-C++技術相結合的方式來實現特定場地內的視覺巡線任務。
控制方面,我們選用了小凌派-RK2206開發板,該開發板運行OpenHarmony請諒解操作系統,并通過串口通訊與LockAI進行高效的數據交互。基于攝像頭傳輸回來的目標坐標數據,我們將運用PID算法精確地對智能車的行駛進行調控。這樣,不僅能夠確保智能車沿著預定線路穩定行駛,還能通過實時數據分析優化行車路徑,提升整體運行效率和穩定性。整個方案集成了先進的圖像識別技術和精準的控制算法,為實現自動化巡線提供了可靠的技術保障。
2、基本知識
2.1、PID算法簡介
PID算法,即比例-積分-微分(Proportional-Integral-Derivative)控制器,是一種在工業控制中廣泛應用的反饋控制機制。它通過計算設定值(目標值)與實際值之間的誤差,并基于此誤差進行調節,以達到穩定系統輸出的目的。其原理如下:
比例(P)控制:比例控制是根據當前誤差值(即設定值與實際值之差)直接按比例調整輸出。它的作用是快速響應誤差,減少誤差幅度。比例系數Kp越大,調節的速度越快,但是過大的Kp會導致系統振蕩。
積分(I)控制:積分控制是對過去所有誤差的累積進行調節,其目的是消除靜差(即系統穩定后仍然存在的誤差)。積分項通過累加過去的誤差來影響控制量,使得即使誤差很小,只要持續存在,也會逐漸增加控制量,直到誤差被完全消除。積分系數Ki需要謹慎選擇,因為太高的積分作用可能導致系統不穩定。
微分(D)控制:微分控制考慮的是誤差的變化率,用于預測誤差的未來趨勢,從而提前采取措施減小誤差。微分項能夠幫助抑制超調現象,提高系統的響應速度和平穩性。然而,由于它對噪聲較為敏感,因此實際應用中往往需要慎重設置微分系數Kd。
在實際的控制過程中我們采用離散型PID控制。在離散時間系統中,假設采樣周期為TT,則離散型PID控制器的輸出u(k)u(k)可以表示為: u(k)=Kpe(k)+Ki∑i=0kTe(i)+Kde(k)?e(k?1)Tu(k)=Kpe(k)+K**i∑i=0kTe(i)+KdT**e(k)?e(k?1) 其中,
KpK**p、KiK**i和 KdK**d分別為比例、積分和微分系數。
e(k)e(k) 代表第kk次采樣時的誤差,即設定值與實際值之差。
TT是采樣時間間隔。
為了更有效地實現積分項的計算,通常采用增量式PID算法,其表達式為: Δu(k)=u(k)?u(k?1)=Kp[e(k)?e(k?1)]+KiTe(k)+Kde(k)?2e(k?1)+e(k?2)TΔu(k)=u(k)?u(k?1)=K**p[e(k)?e(k?1)]+KiT**e(k)+KdT**e(k)?2e(k?1)+e(k?2)
這樣做的好處在于,只需保存最近幾次的誤差值以及上一次的控制量,就可以計算出當前的控制增量Δu(k)Δu(k),從而減少了存儲需求,并且易于編程實現。
2.2、LockAI簡介
凌智視覺模塊(Lockzhiner Vision Module) 是福州市凌睿智捷電子有限公司聯合百度飛槳傾力打造的一款高集成度人工智能視覺模塊,專為邊緣端人工智能和機器視覺應用而設計。讀者如有興趣,可以參考Gitee倉庫(LockAI Gitee倉)
3、實驗內容
3.1、視覺代碼實現
本項目是基于攝像頭的視覺檢測系統,主要功能包括實時捕獲視頻流、提取感興趣區域(ROI)、通過 HSV 閾值分割檢測黑色區域,并計算目標質心位置以確定水平偏移量。系統通過串口將質心 X 坐標發送給外部設備(如小車控制器),同時在圖像上繪制 ROI 邊框和質心位置,并將處理結果發送至編輯模塊進行顯示,便于調試和驗證。代碼采用模塊化設計,支持動態調整攝像頭分辨率,具備良好的靈活性和擴展性,適用于智能車視覺巡線、目標跟蹤等場景。為進一步提升性能,建議增強異常處理機制、優化算法效率,并將關鍵參數提取到配置文件中以便于調整和適配不同環境。整體而言,該系統實現了實時性、可視化與模塊化的結合,為嵌入式視覺應用提供了可靠的技術支持。
#include#include#include#include#include#include#includeintmain(intargc,char*argv[]){ // 設置串口波特率為115200 lockzhiner_vision_module::USART1 usart; if(!usart.Open(115200)) { std::cout <"Failed to open usart."?<< std::endl;? ? ? ? return?1;? ? }? ? // 設置默認攝像頭分辨率? ? int?width =?640;? ? int?height =?480;? ? // 如果命令行參數提供了寬度和高度,則使用它們? ? if?(argc ==?3)? ? {? ? ? ? width = std::stoi(argv[1]);? ? ? ? height = std::stoi(argv[2]);? ? }? ? // 初始化編輯模塊并嘗試連接設備? ? lockzhiner_vision_module::Edit edit;? ? if?(!edit.StartAndAcceptConnection())? ? {? ? ? ? std::cerr <"Error: Failed to start and accept connection."?<< std::endl;? ? ? ? return?EXIT_FAILURE;? ? }? ? std::cout <"Device connected successfully."?<< std::endl;? ? cv::VideoCapture cap;? ? cap.set(cv::CAP_PROP_FRAME_WIDTH, width);? ? cap.set(cv::CAP_PROP_FRAME_HEIGHT, height);? ? cap.open(0);? ? // 獲取實際的幀尺寸? ? double?frameWidth = cap.get(cv::CAP_PROP_FRAME_WIDTH);? ? double?frameHeight = cap.get(cv::CAP_PROP_FRAME_HEIGHT);? ? std::cout <"Frame size: "?<< frameWidth <"x"?<< frameHeight << std::endl;? ? // 定義ROI區域? ? cv::Rect?roi_rect(100,?400,?440,?80);? ? while?(true)? ? {? ? ? ? cv::Mat temp_mat;? ? ? ? cap >> temp_mat;// 獲取新的一幀 if(temp_mat.empty()) { std::cerr <"Warning: Couldn't read a frame from the camera."?<< std::endl;? ? ? ? ? ? continue;? ? ? ? }? ? ? ? // 提取ROI區域,并轉換到HSV色彩空間? ? ? ? cv::Mat roi_image =?temp_mat(roi_rect);? ? ? ? cv::cvtColor(roi_image, roi_image, cv::COLOR_BGR2HSV);?// 注意原代碼中是RGB2HSV,應改為BGR2HSV? ? ? ? // 創建黑白掩膜? ? ? ? cv::Scalar?lower_black(0,?0,?0);? ? ? ? cv::Scalar?upper_black(180,?100,?60);? ? ? ? cv::Mat mask;? ? ? ? cv::inRange(roi_image, lower_black, upper_black, mask);? ? ? ? // 應用掩膜? ? ? ? cv::Mat res;? ? ? ? cv::bitwise_and(roi_image, roi_image, res, mask);? ? ? ? // 計算圖像矩并找到質心? ? ? ? cv::Moments m = cv::moments(mask,?false);? ? ? ? double?cx = m.m10 / (m.m00 +?1e-6);?// 防止除以零? ? ? ? double?cy = m.m01 / (m.m00 +?1e-6);? ? ? ? // 在原始圖像上繪制ROI邊框和質心位置? ? ? ? cv::rectangle(temp_mat, roi_rect, cv::Scalar(255,?0,?0),?2); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 繪制ROI邊框? ? ? ? cv::circle(temp_mat, cv::Point(static_cast
3.2、PID代碼實現
本項目主要通過串口與 LockAI 攝像頭進行通信,并在串口任務中解析出目標的關鍵數據,例如目標的質心坐標、目標檢測區域的大小等信息。這些數據被用作 PID 控制器的反饋輸入,進而計算出 PID 的輸出值。小凌派開發板基于該輸出值實現了麥克納姆輪的運動解算。只需輸入期望的 X 軸、Y 軸以及旋轉 W 軸的速度,即可通過解算函數計算出四個輪子對應的速度。各軸的速度會自動疊加,確保運動的平滑性與精確性。將 PID 的輸出結果輸入到麥克納姆輪的解算函數中,即可實現對小車車身姿態和運動的精準控制。
floatPID_Calc(PidTypeDef *pid,floatref,floatset){ if(pid == NULL) { return0.0f; } pid->error[2] = pid->error[1]; pid->error[1] = pid->error[0]; pid->set=set; pid->fdb =ref; pid->error[0] =set-ref; if(pid->mode == PID_POSITION) { pid->Pout = pid->Kp * pid->error[0]; pid->Iout += pid->Ki * pid->error[0]; pid->Dbuf[2] = pid->Dbuf[1]; pid->Dbuf[1] = pid->Dbuf[0]; pid->Dbuf[0] = (pid->error[0] - pid->error[1]); pid->Dout = pid->Kd * pid->Dbuf[0]; LimitMax(pid->Iout, pid->max_iout); pid->out= pid->Pout + pid->Iout + pid->Dout; LimitMax(pid->out, pid->max_out); } elseif(pid->mode == PID_DELTA) { pid->Pout = pid->Kp * (pid->error[0] - pid->error[1]); pid->Iout = pid->Ki * pid->error[0]; pid->Dbuf[2] = pid->Dbuf[1]; pid->Dbuf[1] = pid->Dbuf[0]; pid->Dbuf[0] = (pid->error[0] -2.0f* pid->error[1] + pid->error[2]); pid->Dout = pid->Kd * pid->Dbuf[0]; pid->out+= pid->Pout + pid->Iout + pid->Dout; LimitMax(pid->out, pid->max_out); } returnpid->out;}voidUserControl(){ WheelControl wheelControls[WHEELS_COUNT]; floatvx =0;// X方向線速度,單位:m/s floatvy =0;// Y方向線速度,單位:m/s floatw =0; // 角速度,單位:rad/s CtrolInit(); for(;;) { // PID_Calc(&PWMPid[0], x, 320); // PID_Calc(&PWMPid[0], x, 320); if(FirstRec ==1) { // 檢測用 // PID_Calc(&PWMPid[2], x, 240); // PID_Calc(&PWMPid[1], s, 10000); // calculateWheelPWMSpeeds(-PWMPid[1].out, vy, PWMPid[2].out, wheelControls); // 循跡用 PID_Calc(&PWMPid[2], x,240); calculateWheelPWMSpeeds(-5, vy, PWMPid[2].out, wheelControls); // 設置方向GPIO LzGpioSetVal(GPIO0_PA5, wheelControls[0].direction);// 右前 LzGpioSetVal(GPIO0_PA3, wheelControls[3].direction);// 右后 LzGpioSetVal(GPIO0_PA1, wheelControls[2].direction);// 左后 LzGpioSetVal(GPIO0_PA0, wheelControls[1].direction);// 左前 // 啟動PWM IoTPwmStart(RU_B4, wheelControls[0].pwm,1000);// 右前 IoTPwmStart(RD_B6, wheelControls[3].pwm,1000);// 右后 IoTPwmStart(LD_C7, wheelControls[2].pwm,1000);// 左后 IoTPwmStart(LU_C3, wheelControls[1].pwm,1000);// 左前 } LOS_Msleep(1); }}
-
PID
+關注
關注
37文章
1482瀏覽量
88099 -
AI
+關注
關注
88文章
35168瀏覽量
280150 -
開發板
+關注
關注
25文章
5683瀏覽量
104885
發布評論請先 登錄
AI模型部署邊緣設備的奇妙之旅:如何實現手寫數字識別
AI模型部署邊緣設備的奇妙之旅:如何在邊緣端部署OpenCV
AI模型部署邊緣設備的奇妙之旅:目標檢測模型
AI模型部署邊緣設備的奇妙之旅:邊緣端設備的局域網視頻流傳輸方案
邊緣設備的奇妙之旅:在小凌派-RK2206上部署AI模型來實現視覺巡線
Deepseek海思SD3403邊緣計算AI產品系統
嵌入式邊緣AI應用開發指南
AI模型部署邊緣設備的奇妙之旅:如何在邊緣端部署OpenCV

AI模型部署邊緣設備的奇妙之旅:目標檢測模型

AI模型部署邊緣設備的奇妙之旅:邊緣端設備的局域網視頻流傳輸方案

評論