全自主巡航無人機項目思路:STM32/PX4 + ROS + AI 實現從傳感融合到智能規劃的端到端解決方案

1. 項目概述

本項目旨在設計并實現一款高度自主的自動巡航無人機系統。該系統能夠按照預設路徑自主飛行,完成各種巡航任務,如電力巡線、森林防火、邊境巡邏和災害監測等。

1.1 系統特點

  • 基于STM32F4和PX4的高性能嵌入式飛控系統
  • 多傳感器融合技術實現精確定位和姿態估計
  • Wi-Fi/4G雙模無線通信,支持遠程控制和數據傳輸
  • 基于ROS的智能路徑規劃算法,實現復雜環境下的自主導航
  • 模塊化設計,易于擴展和維護

1.2 技術棧

  • 嵌入式開發:STM32F4 MCU,PX4飛控系統,C/C++編程語言
  • 傳感器集成:GPS、IMU(加速度計、陀螺儀、磁力計)、氣壓計
  • 無線通信:Wi-Fi模塊(短距離),4G模塊(遠距離),MAVLink協議
  • 路徑規劃:ROS框架,Python編程語言
  • 開發工具:STM32CubeIDE,QGroundControl地面站軟件

2. 系統設計

2.1 硬件架構

硬件系統主要由以下模塊構成:

  1. 飛控主板:采用STM32F4系列MCU,運行PX4飛控系統
  2. 定位模塊:集成GPS模塊,提供精確的全球定位信息
  3. 姿態測量:IMU(慣性測量單元)包含加速度計、陀螺儀和磁力計
  4. 高度測量:氣壓計用于測量相對高度和垂直速度
  5. 通信模塊:Wi-Fi模塊用于短距離高帶寬通信,4G模塊用于遠距離通信
  6. 動力系統:電機驅動控制四個無刷電機
  7. 視覺系統:高清攝像頭用于環境感知和目標識別
  8. 電源系統:鋰電池供電,配備電源管理模塊

2.2 軟件架構

軟件系統主要包括以下組件:

  1. PX4飛控系統:

    • 傳感器驅動:負責讀取和處理各類傳感器數據
    • 姿態估計:使用擴展卡爾曼濾波(EKF)融合IMU、GPS等數據
    • 位置控制:實現精確的位置保持和軌跡跟蹤
    • 飛行模式:包括手動、半自動、全自動等多種飛行模式
    • 通信模塊:基于MAVLink協議與地面站和ROS節點通信
  2. 地面站(QGroundControl):

    • 飛行監控:實時顯示飛行狀態、位置和傳感器數據
    • 任務規劃:設計巡航路徑,設置航點和任務參數
    • 參數配置:調整PID參數,設置飛行限制等
    • 固件更新:支持遠程固件升級
  3. ROS(機器人操作系統)節點:

    • 路徑規劃:使用A*或RRT算法進行全局路徑規劃
    • 障礙物檢測:基于視覺或激光雷達數據進行實時障礙物檢測
    • SLAM建圖:同步定位與地圖構建,用于未知環境導航
  4. 通信流程:

    • PX4飛控系統通過MAVLink協議與地面站和ROS節點進行雙向通信
    • 地面站發送控制指令和任務信息給飛控系統
    • ROS節點將規劃的路徑、檢測到的障礙物信息發送給飛控系統
    • 飛控系統實時反饋飛行狀態和傳感器數據給地面站和ROS節點

這種分層的軟件架構設計具有以下優勢:

  • 模塊化:各個組件功能明確,便于開發和維護
  • 靈活性:可以根據需求easily添加或替換功能模塊
  • 可擴展性:支持添加新的傳感器和算法以增強系統能力
  • 可靠性:核心飛控功能由成熟的PX4系統保障,提高系統穩定性

3. 核心代碼實現

3.1 姿態估計

姿態估計是自動巡航無人機系統的關鍵模塊之一。我們使用四元數表示姿態,并采用互補濾波算法融合加速度計和陀螺儀數據。以下是核心代碼實現:

#include <math.h>// 四元數結構體
typedef struct {float w, x, y, z;
} Quaternion;// 姿態估計參數
#define dt 0.01f  // 采樣周期
#define alpha 0.98f  // 互補濾波系數Quaternion attitude = {1.0f, 0.0f, 0.0f, 0.0f};  // 初始姿態void attitudeUpdate(float acc[3], float gyro[3]) {// 歸一化加速度float accMag = sqrt(acc[0]*acc[0] + acc[1]*acc[1] + acc[2]*acc[2]);float ax = acc[0] / accMag;float ay = acc[1] / accMag;float az = acc[2] / accMag;// 基于加速度計算俯仰角和橫滾角float pitch = atan2(-ax, sqrt(ay*ay + az*az));float roll = atan2(ay, az);// 構造基于加速度的四元數Quaternion qAcc;qAcc.w = cos(roll/2) * cos(pitch/2);qAcc.x = cos(roll/2) * sin(pitch/2);qAcc.y = sin(roll/2) * cos(pitch/2);qAcc.z = -sin(roll/2) * sin(pitch/2);// 基于陀螺儀數據的四元數微分方程float qDot[4];qDot[0] = 0.5f * (-attitude.x*gyro[0] - attitude.y*gyro[1] - attitude.z*gyro[2]);qDot[1] = 0.5f * (attitude.w*gyro[0] + attitude.y*gyro[2] - attitude.z*gyro[1]);qDot[2] = 0.5f * (attitude.w*gyro[1] - attitude.x*gyro[2] + attitude.z*gyro[0]);qDot[3] = 0.5f * (attitude.w*gyro[2] + attitude.x*gyro[1] - attitude.y*gyro[0]);// 更新姿態四元數attitude.w += qDot[0] * dt;attitude.x += qDot[1] * dt;attitude.y += qDot[2] * dt;attitude.z += qDot[3] * dt;// 互補濾波attitude.w = alpha * attitude.w + (1-alpha) * qAcc.w;attitude.x = alpha * attitude.x + (1-alpha) * qAcc.x;attitude.y = alpha * attitude.y + (1-alpha) * qAcc.y;attitude.z = alpha * attitude.z + (1-alpha) * qAcc.z;// 歸一化四元數float mag = sqrt(attitude.w*attitude.w + attitude.x*attitude.x + attitude.y*attitude.y + attitude.z*attitude.z);attitude.w /= mag;attitude.x /= mag;attitude.y /= mag;attitude.z /= mag;
}

代碼說明:

  1. 我們定義了一個Quaternion結構體來表示姿態四元數。
  2. attitudeUpdate函數接收加速度計和陀螺儀的原始數據作為輸入。
  3. 首先處理加速度計數據,計算出俯仰角和橫滾角,并構造對應的四元數。
  4. 然后利用陀螺儀數據,通過四元數微分方程更新姿態。
  5. 使用互補濾波算法融合加速度計和陀螺儀的結果,alpha參數決定了各自的權重。
  6. 最后對結果四元數進行歸一化,確保其表示有效的旋轉。

這種方法結合了加速度計的長期穩定性和陀螺儀的短期準確性,能夠得到更加精確的姿態估計。

3.2 位置控制

位置控制是實現自動巡航的關鍵。我們使用PID控制器來實現精確的位置保持和軌跡跟蹤。以下是簡化的PID控制器實現:

#include <math.h>typedef struct {float Kp, Ki, Kd;  // PID參數float integral;    // 積分項float prevError;   // 上一次的誤差
} PIDController;// 初始化PID控制器
void initPIDController(PIDController* pid, float Kp, float Ki, float Kd) {pid->Kp = Kp;pid->Ki = Ki;pid->Kd = Kd;pid->integral = 0.0f;pid->prevError = 0.0f;
}// PID控制器更新函數
float updatePID(PIDController* pid, float setpoint, float measurement, float dt) {float error = setpoint - measurement;// 比例項float P = pid->Kp * error;// 積分項pid->integral += error * dt;float I = pid->Ki * pid->integral;// 微分項float derivative = (error - pid->prevError) / dt;float D = pid->Kd * derivative;// 計算輸出float output = P + I + D;// 更新上一次誤差pid->prevError = error;return output;
}// 位置控制主函數
void positionControl(float targetPosition[3], float currentPosition[3], float* outputs) {static PIDController pidX, pidY, pidZ;// 初始化PID控制器(僅在第一次調用時執行)static int initialized = 0;if (!initialized) {initPIDController(&pidX, 1.0f, 0.1f, 0.05f);  // 示例PID參數initPIDController(&pidY, 1.0f, 0.1f, 0.05f);initPIDController(&pidZ, 1.5f, 0.15f, 0.1f);  // 垂直方向通常需要更強的控制initialized = 1;}// 更新每個軸的PID控制器float dt = 0.01f;  // 假設控制周期為10msoutputs[0] = updatePID(&pidX, targetPosition[0], currentPosition[0], dt);outputs[1] = updatePID(&pidY, targetPosition[1], currentPosition[1], dt);outputs[2] = updatePID(&pidZ, targetPosition[2], currentPosition[2], dt);
}

代碼說明:

  1. PIDController結構體包含PID控制器的參數和狀態。
  2. initPIDController函數用于初始化PID控制器的參數。
  3. updatePID函數實現了PID控制算法的核心邏輯,包括比例、積分和微分三個部分。
  4. positionControl函數是位置控制的主函數,它為X、Y、Z三個軸分別創建和更新PID控制器。
  5. 控制器的輸出可以直接用作無人機的速度或加速度指令,具體取決于飛控系統的接口設計。

這個簡化的PID控制器為每個軸獨立控制,在實際應用中可能需要考慮軸間耦合和更復雜的動力學模型。

3.3 路徑規劃

路徑規劃模塊使用ROS(機器人操作系統)和Python實現。我們采用A*算法進行全局路徑規劃。以下是簡化的實現:

import rospy
from geometry_msgs.msg import PoseStamped
from nav_msgs.msg import OccupancyGrid, Path
import numpy as npclass AStarPlanner:def __init__(self):self.map = Noneself.start = Noneself.goal = Noneself.path = []# ROS節點初始化rospy.init_node('astar_planner')self.map_sub = rospy.Subscriber('/map', OccupancyGrid, self.map_callback)self.start_sub = rospy.Subscriber('/start_pose', PoseStamped, self.start_callback)self.goal_sub = rospy.Subscriber('/goal_pose', PoseStamped, self.goal_callback)self.path_pub = rospy.Publisher('/path', Path, queue_size=1)def map_callback(self, msg):self.map = np.array(msg.data).reshape((msg.info.height, msg.info.width))def start_callback(self, msg):self.start = (int(msg.pose.position.x), int(msg.pose.position.y))self.plan()def goal_callback(self, msg):self.goal = (int(msg.pose.position.x), int(msg.pose.position.y))self.plan()def heuristic(self, a, b):return np.sqrt((b[0] - a[0]) ** 2 + (b[1] - a[1]) ** 2)def get_neighbors(self, node):directions = [(0,1),(0,-1),(1,0),(-1,0),(1,1),(1,-1),(-1,1),(-1,-1)]neighbors = []for direction in directions:neighbor = (node[0] + direction[0], node[1] + direction[1])if 0 <= neighbor[0] < self.map.shape[0] and 0 <= neighbor[1] < self.map.shape[1]:if self.map[neighbor] == 0:  # 假設0表示自由空間neighbors.append(neighbor)return neighborsdef astar(self):open_set = set([self.start])closed_set = set()came_from = {}g_score = {self.start: 0}f_score = {self.start: self.heuristic(self.start, self.goal)}while open_set:current = min(open_set, key=lambda x: f_score[x])if current == self.goal:path = []while current in came_from:path.append(current)current = came_from[current]path.append(self.start)return path[::-1]open_set.remove(current)closed_set.add(current)for neighbor in self.get_neighbors(current):if neighbor in closed_set:continuetentative_g_score = g_score[current] + self.heuristic(current, neighbor)if neighbor not in open_set:open_set.add(neighbor)elif tentative_g_score >= g_score[neighbor]:continuecame_from[neighbor] = currentg_score[neighbor] = tentative_g_scoref_score[neighbor] = g_score[neighbor] + self.heuristic(neighbor, self.goal)return None  # 沒有找到路徑def plan(self):if self.map is not None and self.start is not None and self.goal is not None:self.path = self.astar()if self.path:# 發布路徑消息path_msg = Path()path_msg.header.frame_id = "map"path_msg.header.stamp = rospy.Time.now()for point in self.path:pose = PoseStamped()pose.pose.position.x = point[0]pose.pose.position.y = point[1]path_msg.poses.append(pose)self.path_pub.publish(path_msg)else:rospy.logwarn("No path found")if __name__ == '__main__':planner = AStarPlanner()rospy.spin()

代碼說明:

  1. AStarPlanner類實現了A*路徑規劃算法。

  2. 使用ROS的訂閱者接收地圖、起點和終點信息:

    • /map: 接收占用柵格地圖
    • /start_pose: 接收起點位置
    • /goal_pose: 接收終點位置
  3. map_callback,?start_callback,?goal_callback?函數處理接收到的數據。

  4. heuristic函數計算兩點間的歐幾里得距離,作為A*算法的啟發函數。

  5. get_neighbors函數返回給定節點的有效鄰居節點。

  6. astar函數實現了A*算法的核心邏輯:

    • 使用open_set和closed_set來管理待探索和已探索的節點
    • f_score = g_score + heuristic,用于選擇最優節點
    • 當找到目標節點時,通過came_from字典回溯構建路徑
    • 如果無法找到路徑,返回None
  7. plan函數是路徑規劃的主函數:

    • 檢查是否已接收到必要的信息(地圖、起點、終點)
    • 調用astar函數進行路徑規劃
    • 如果找到路徑,將其轉換為ROS的Path消息并發布
  8. 在主函數中,我們創建AStarPlanner實例并使用rospy.spin()保持節點運行。

個路徑規劃模塊的主要特點:

  • 使用ROS框架,便于與其他ROS節點(如定位、控制模塊)集成
  • 實現了A*算法,能夠在給定的柵格地圖上找到最優路徑
  • 考慮了障礙物避免,只在自由空間中規劃路徑
  • 支持實時規劃,當接收到新的起點或終點時會重新規劃
  • 將規劃結果以標準的ROS Path消息格式發布,便于其他模塊使用

在實際應用中,這個基礎實現可以進一步優化:

  1. 添加路徑平滑處理,使路徑更適合無人機飛行
  2. 實現動態避障,考慮移動障礙物
  3. 優化A*算法,如使用Jump Point Search等變體提高效率
  4. 添加局部路徑規劃,以應對地圖變化或未知障礙物

4. 項目總結

本自動巡航無人機系統集成了多項關鍵技術:

  1. 基于STM32F4和PX4的嵌入式飛控系統,實現了穩定的飛行控制
  2. 多傳感器融合的姿態估計算法,提高了飛行姿態的精確度
  3. PID控制器實現的位置控制,確保了精確的路徑跟蹤
  4. 基于ROS的A*路徑規劃算法,實現了智能化的任務規劃

通過這些模塊的協同工作,系統能夠完成復雜環境下的自主巡航任務。

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/44832.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/44832.shtml
英文地址,請注明出處:http://en.pswp.cn/web/44832.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

MYSQL--第八次作業

MYSQL–第八次作業 一、備份與恢復 環境搭建&#xff1a; CREATE DATABASE booksDB; use booksDB;CREATE TABLE books ( bk_id INT NOT NULL PRIMARY KEY, bk_title VARCHAR(50) NOT NULL, copyright YEAR NOT NULL );CREATE TABLE authors ( auth_id INT NOT NULL PRI…

geoServer在windows中下載安裝部署詳細操作教程

這里寫目錄標題 1.安裝環境檢查2.下載安裝包&#xff08;1&#xff09;進入下載地址&#xff1a;&#xff08;2&#xff09;以下載最新版為例&#xff0c;點擊“Stable GeoServer”下載&#xff08;3&#xff09;安裝有兩種方式&#xff08;4&#xff09;我這里選擇下載war包 3…

python作業三

1.使用requests模塊獲取這個json文件http://java-api.super-yx.com/html/hello.json 2.將獲取到的json轉為dict 3.將dict保存為hello.json文件 4.用io流寫一個copy(src,dst)函數,復制hello.json到C:\hello.json import json import shutilimport requests #使用requests模塊獲…

Qt MV架構-視圖類

一、基本概念 在MV架構中&#xff0c;視圖包含了模型中的數據項&#xff0c;并將它們呈現給用戶。數據項的表示方法&#xff0c;可能和數據項在存儲時用的數據結構完全不同。 這種內容與表現分離之所以能夠實現&#xff0c;是因為使用了 QAbstractItemModel提供的一個標準模…

`nmap`模塊是一個用于與Nmap安全掃描器交互的庫

在Python中&#xff0c;nmap模塊是一個用于與Nmap安全掃描器交互的庫。Nmap&#xff08;Network Mapper&#xff09;是一個開源工具&#xff0c;用于發現網絡上的設備和服務。雖然Python的nmap模塊可能不是官方的Nmap庫&#xff08;因為Nmap本身是用C/C編寫的&#xff09;&…

基于JavaSpringBoot+Vue+uniapp微信小程序校園宿舍管理系統設計與實現

基于JavaSpringBootVueuniapp微信小程序實現校園宿舍管理系統設計與實現 目錄 第一章 緒論 1.1 研究背景 1.2 研究現狀 1.3 研究內容 第二章 相關技術介紹 2.1 Java語言 2.2 HTML網頁技術 2.3 MySQL數據庫 2.4 Springboot 框架介紹 2.5 VueJS介紹 2.6 ElementUI介紹…

視頻轉換、提取音頻、視頻加水印、視頻去水印、音頻轉換、分割合并壓縮等,批量還幾乎免費

「想轉就轉視頻音頻助手」免費版來襲&#xff01; 在數字化時代&#xff0c;視頻和音頻處理已成為我們日常生活的一部分。無論是制作個人視頻博客、編輯家庭影片&#xff0c;還是處理音頻文件&#xff0c;我們都在尋找一個強大而易于使用的解決方案。今天&#xff0c;我要向您…

基于大語言模型(LLM)的合成數據生成、策展和評估的綜述

節前&#xff0c;我們星球組織了一場算法崗技術&面試討論會&#xff0c;邀請了一些互聯網大廠朋友、參加社招和校招面試的同學。 針對算法崗技術趨勢、大模型落地項目經驗分享、新手如何入門算法崗、該如何準備、面試常考點分享等熱門話題進行了深入的討論。 合集&#x…

【JVM實戰篇】內存調優:內存泄露危害+內存監控工具介紹+內存泄露原因介紹

文章目錄 內存調優內存溢出和內存泄漏內存泄露帶來什么問題內存泄露案例演示內存泄漏的常見場景場景一場景二 解決內存溢出的方法常用內存監控工具Top命令優缺點 VisualVM軟件、插件優缺點監控本地Java進程監控服務器的Java進程&#xff08;生產環境不推薦使用&#xff09; Art…

【圖解大數據技術】流式計算:Spark Streaming、Flink

【圖解大數據技術】流式計算&#xff1a;Spark Streaming、Flink 批處理 VS 流式計算Spark StreamingFlinkFlink簡介Flink入門案例Streaming Dataflow Flink架構Flink任務調度與執行task slot 和 task EventTime、Windows、WatermarksEventTimeWindowsWatermarks 批處理 VS 流式…

如何查找電腦的MAC地址

一. 什么是mac地址&#xff1f; mac地址本質上幫助我們連接到我們遇到的大多數本地網絡。每個網絡適配器通常由網絡接口??控制器(NIC) 制造商分配一個唯一的 mac 地址。 二. 如何查找mac地址 1.點擊網絡和Internet設置 2.點擊WLAN點擊硬件屬性 3.即可查看mac地址

智慧城市3d數據可視化系統提升信息匯報的時效和精準度

在信息大爆炸的時代&#xff0c;數據的力量無可估量。而如何將這些數據以直觀、高效的方式呈現出來&#xff0c;成為了一個亟待解決的問題。為此&#xff0c;我們推出了全新的3D可視化數據大屏系統&#xff0c;讓數據“躍然屏上”&#xff0c;助力您洞察先機&#xff0c;決勝千…

從零開始實現大語言模型(五):縮放點積注意力機制

1. 前言 縮放點積注意力機制(scaled dot-product attention)是OpenAI的GPT系列大語言模型所使用的多頭注意力機制(multi-head attention)的核心,其目標與前文所述簡單自注意力機制完全相同,即輸入向量序列 x 1 , x 2 , ? ? , x n x_1, x_2, \cdots, x_n x

pytorch訓練的時候 shm共享內存不足,導致訓練停止

1.查看shm情況 df -h /dev/shm內存已經滿了&#xff0c;因為之前訓練多次訓練意外停止到shm中的緩存不能及時被清理 2、手動清理shm 依然沒被釋放 3、查看關聯的進程&#xff0c;一個一個kill lsof |grep deletedkill -9 46619 44618 44617 。。。。。4、搞定

Spring @Scheduled學習

一. Jdk中的定時任務 我們平時在 Spring 項目中會使用 Scheduled 開啟定時任務&#xff1b; jdk 中其實也提供了定時任務線程池 ScheduledThreadPool&#xff0c;我們可以直接通過 Executors 工具類獲取&#xff1b; // 創建了核心線程數為 2 的 ScheduledThreadPool 對象 S…

ROS2 + 科大訊飛 初步實現機器人語音控制

環境配置&#xff1a; 電腦端&#xff1a; ubuntu22.04實體機作為上位機 ROS版本&#xff1a;ros2-humble 實體機器人&#xff1a; STM32 思嵐A1激光雷達 科大訊飛語音SDK 訊飛開放平臺-以語音交互為核心的人工智能開放平臺 實現步驟&#xff1a; 1. 下載和處理科大訊飛語音模…

開發指南048-前端模塊版本

平臺前端框架內置了一個文件version.vue <template> <div> <br> 應用名稱: {{name}} <br> 當前版本&#xff1a;{{version}} <br> 服務網關: {{gateway}} </div> </template> <scrip…

qt 創建一個包含兩按鈕,且安裝和自定義控件間沒有間距

在 Qt 中創建一個包含兩個按鈕且按鈕之間沒有間距的自定義控件&#xff0c;你可以使用 QHBoxLayout 或 QVBoxLayout&#xff08;取決于你希望按鈕是水平排列還是垂直排列&#xff09;&#xff0c;并設置布局的間距為 0。以下是一個簡單的示例&#xff0c;展示了如何創建一個水平…

Dataset for Stable Diffusion

1.Dataset for Stable Diffusion 筆記來源&#xff1a; 1.Flickr8k數據集處理 2.處理Flickr8k數據集 3.Github&#xff1a;pytorch-stable-diffusion 4.Flickr 8k Dataset 5.dataset_flickr8k.json 1.1 Dataset 采用Flicker8k數據集&#xff0c;該數據集有兩個文件&#xff…

Node.js_mongodb用戶名和密碼操作

mongodb用戶名和密碼操作 查看用戶密碼創建管理員用戶和密碼mongodb的目標是實現快速簡單部署,所以存在很多安全問題 默認配置下沒有用戶和密碼,無需身份驗證即可登錄,不像mysql那樣需要登錄才能操作數據庫本身安全問題:升級3.0以上版本查看用戶密碼 密碼是加密存儲的,并且…