網(wǎng)站建設(shè)有哪些常用行為個人自媒體創(chuàng)意名字
鶴壁市浩天電氣有限公司
2026/01/24 08:45:36
網(wǎng)站建設(shè)有哪些常用行為,個人自媒體創(chuàng)意名字,家具行業(yè)網(wǎng)站建設(shè),網(wǎng)址導(dǎo)航建站基礎(chǔ)講解
基礎(chǔ)術(shù)語
消息#xff1a;數(shù)據(jù)格式模板#xff08;類似 “語言語法”#xff09;#xff0c;定義數(shù)據(jù)字段#xff08;如時間戳、具體參數(shù)#xff09;#xff0c;所有消息必須包含timestamp#xff08;時間戳#xff09;字段主題#xff1a;消息的 “通信通…基礎(chǔ)講解基礎(chǔ)術(shù)語消息數(shù)據(jù)格式模板類似 “語言語法”定義數(shù)據(jù)字段如時間戳、具體參數(shù)所有消息必須包含timestamp時間戳字段主題消息的 “通信通道”類似 “訂單傳遞渠道”同一消息格式可對應(yīng)多個獨立主題模塊通過主題收發(fā)數(shù)據(jù)模塊PX4 中承擔特定功能的單元類似 “廚師、服務(wù)員”發(fā)布/訂閱uORB Message的定義與轉(zhuǎn)換定義在msg/目錄下創(chuàng)建.msg文件指定字段名、數(shù)據(jù)類型和注釋uint64 timestamp # 系統(tǒng)啟動后的時間戳微秒 uint16 customer_table_id # 顧客餐桌ID float32 pasta_temperature # 意面溫度℃編譯轉(zhuǎn)換.msg文件無法直接用于代碼編譯時會自動轉(zhuǎn)換為C/C結(jié)構(gòu)體生成的頭文件位于build/px4_sitl_default/uORB/topics/路徑下uORB Topic的創(chuàng)建規(guī)則編譯系統(tǒng)自動注冊與消息名稱相同的主題自定義主題在.msg文件末尾添加# TOPICS 主題1 主題2注釋即可創(chuàng)建多個基于同一消息格式的獨立主題# TOPICS pasta_cook pasta_orderuORB 發(fā)布與訂閱的實現(xiàn)發(fā)布Publication步驟包含發(fā)布工具的頭文件 - 定義發(fā)布對象指定主題ID - 填充消息結(jié)構(gòu)體 - 調(diào)用publish()發(fā)布示例#includeuORB/Publication.hpp// 封裝了 “發(fā)布消息” 所需的全部核心接口#includeuORB/topics/safety.h// 引入 safety 主題對應(yīng)的 “消息結(jié)構(gòu)體定義”// 定義發(fā)布對象主題safetyuORB::Publicationsafety_s_to_safety{ORB_ID(safety)};safety_s _safety{};// 消息結(jié)構(gòu)體實例// 填充并發(fā)布消息_safety.safety_offtrue;// 安全保護關(guān)閉_safety.timestamphrt_absolute_time();_to_safety.publish(_safety);// 發(fā)布訂閱Subscription包含訂閱工具頭文件 - 定義訂閱對象制定主題ID - 檢查主題更新 - 調(diào)用copy()拷貝消息數(shù)據(jù)示例#includeuORB/Subscription.hpp#includeuORB/topics/safety.h// 定義訂閱對象主題safetyuORB::Subscription _safety_sub{ORB_ID(safety)};safety_s _safety{};// 本地存儲消息的結(jié)構(gòu)體// 檢查更新并拷貝數(shù)據(jù)if(_safety_sub.updated()){// 判斷是否有新消息_safety_sub.copy(_safety);// 拷貝消息到本地// 處理消息如允許電機解鎖}實用技巧如果想搜索與特定主題相關(guān)的uORB 發(fā)布 / 訂閱實例建議使用ORB_ID(topic-name)作為搜索關(guān)鍵詞而非直接搜索topic-name在瀏覽器中打開PX4-Autopilot的 GitHub 倉庫https://github.com/PX4/PX4-Autopilot按下.句點鍵頁面會自動切換為交互式 VS Code 編輯器。此時按下CtrlShiftF即可打開全局搜索框快速搜索你需要的內(nèi)容注意時間戳是所有消息的必填字段記錄了消息的發(fā)布時間訂閱者可以通過它判斷消息的實效性.msg文件不能直接在代碼中使用在編譯階段這些.msg文件會被解析并轉(zhuǎn)換為 C/C 結(jié)構(gòu)體以便代碼庫調(diào)用網(wǎng)址https://px4.io/px4-uorb-explained-part-1/https://px4.io/px4-uorb-explained-part-2/例程講解例程#includepx4_platform_common/log.h#includepx4_platform_common/px4_config.h#includepx4_platform_common/tasks.h#includepx4_platform_common/posix.h#includeunistd.h#includestdio.h#includepoll.h#includestring.h#includemath.h#includeuORB/uORB.h#includeuORB/topics/vehicle_acceleration.h#includeuORB/topics/vehicle_attitude.h__EXPORTintuorb_test_main(intargc,char*argv[]);intuorb_test_main(intargc,char*argv[]){PX4_INFO(Hello Sky!);// 訂閱 vehicle_acceleration 主題intsensor_sub_fdorb_subscribe(ORB_ID(vehicle_acceleration));// sensor_sub_fd 傳感器訂閱句柄訂閱失敗會返回負數(shù)orb_set_interval(sensor_sub_fd,200);// 訂閱頻率配置函數(shù)每 200 ms訂閱一次// 初始化姿態(tài)主題的發(fā)布者structvehicle_attitude_satt;//定義姿態(tài)數(shù)據(jù)結(jié)構(gòu)體存儲要發(fā)布的姿態(tài)數(shù)據(jù)memset(att,0,sizeof(att));// 變量內(nèi)存起始地址 要填充的字節(jié)值 要填充的字節(jié)數(shù)把 att 變量的所有內(nèi)存字節(jié)都變成0orb_advert_tatt_puborb_advertise(ORB_ID(vehicle_attitude),att);// 定義要監(jiān)聽的事件px4_pollfd_struct_tfds[]{{.fdsensor_sub_fd,.eventsPOLLIN},};interror_counter0;// 記錄錯誤次數(shù)for(inti0;i5;i){intpoll_retpx4_poll(fds,1,1000);// 阻塞等待事件if(poll_ret0)// 超時{PX4_ERR(Got no data within a sencond);}elseif(poll_ret0)//錯誤{if(error_counter0||error_counter%500)// 限制錯誤輸出頻率避免刷屏{PX4_ERR(ERROR return value from poll():%d,poll_ret);}error_counter;}else// 有事件發(fā)生{if(fds[0].reventsPOLLIN)// 判斷是否是fds[0]的事件發(fā)生{structvehicle_acceleration_saccel;orb_copy(ORB_ID(vehicle_acceleration),sensor_sub_fd,accel);// 把ORB系統(tǒng)中緩存的最新加速度數(shù)據(jù)拷貝到本地accel變量中PX4_INFO(Accelerometer: %8.4f %8.4f %8.4f,(double)accel.xyz[0],(double)accel.xyz[1],(double)accel.xyz[2]);// 打印// 假處理真實姿態(tài)解算需要用IMU的加速度角速度通過卡爾曼濾波等算法計算四元數(shù)att.q[0]accel.xyz[0];att.q[1]accel.xyz[1];att.q[2]accel.xyz[2];// 發(fā)布數(shù)據(jù)orb_publish(ORB_ID(vehicle_attitude),att_pub,att);}}}PX4_INFO(exiting);return0;}注釋int sensor_sub_fd orb_subscribe(ORB_ID(vehicle_acceleration));向 uORB 管理器 “訂閱” vehicle_acceleration類型的 uORB 消息intorb_subscribe(conststructorb_metadata*meta)// meta uORB 消息的 “元數(shù)據(jù)指針”orb_set_interval(sensor_sub_fd, 200);控制消息訂閱更新頻率intorb_set_interval(inthandle,unsignedintinterval)// handle uORB 訂閱句柄// interval 最小更新時間間隔單位msmemset(att, 0, sizeof(att));把 att 變量的所有內(nèi)存字節(jié)都變成0void*memset(void*__dest,int__ch,size_t__len)// __dest 變量內(nèi)存起始地址// __ch 要填充的字節(jié)值// __len 要填充的字節(jié)數(shù)orb_advert_t att_pub orb_advertise(ORB_ID(vehicle_attitude), att);向 uORB 管理器 “宣告”我要發(fā)布某個類型的 uORB 消息orb_advert_torb_advertise(conststructorb_metadata*meta,constvoid*data)// meta uORB 消息的 “元數(shù)據(jù)指針”// data 可選初始數(shù)據(jù)指針首次宣告時可傳入該消息的初始化數(shù)據(jù)也可傳入 NULL// 返回值成功則返回有效句柄失敗返回無效句柄常量px4_pollfd_struct_t fds[] { { .fd sensor_sub_fd, .events POLLIN }, /* there could be more file descriptors here, in the form like: * { .fd other_sub_fd, .events POLLIN }, */ };定義了一個 px4_pollfd_struct_t 類型的數(shù)組 fds 并為數(shù)組的第一個元素顯示初始化 fd 和 event 兩個成員typedefstruct{/* This part of the struct is POSIX-like */intfd;/* The descriptor being polled */px4_pollevent_tevents;/* The input event flags */px4_pollevent_trevents;/* The output event flags *//* Required for PX4 compatibility */px4_sem_t*sem;/* Pointer to semaphore used to post output event */void*priv;/* For use by drivers */}px4_pollfd_struct_t;// fd 要監(jiān)聽的文件描述符。對應(yīng) ORB 訂閱句柄/設(shè)備句柄// events 要監(jiān)聽的事件類型。POLLIN 有數(shù)據(jù)可讀傳感器數(shù)據(jù)、ORB主題更新POLLOUT 數(shù)據(jù)讀寫比如向串口發(fā)數(shù)據(jù)POLLERR 通道錯誤比如傳感器斷開// revents 實際發(fā)生的事件類型。輸出參數(shù)用戶不能初始化只能在 px4_poll() 返回后讀取??赏ㄟ^ if(fds[0].revents POLLIN) 判斷是否發(fā)生目標事件// sem 信號量指針。當 fd 對應(yīng)的通道發(fā)生目標事件時px4_poll() 會自動調(diào)用 px4_sem_post(sem) 觸發(fā)信號量喚醒等待信號量的線程普通 ORB 訂閱場景無需手動設(shè)置PX4 內(nèi)核會主動管理只有驅(qū)動開發(fā)寫一個新的 IMU 傳感器驅(qū)動時才需要手動配置// priv 私有數(shù)據(jù)指針。讓讓驅(qū)動模塊可以將自定義數(shù)據(jù)比如設(shè)備私有結(jié)構(gòu)體、配置參數(shù)綁定到這個 pollfd 上驅(qū)動初始化時填充用戶只讀不寫int poll_ret px4_poll(fds, 1, 1000);監(jiān)聽多個文件描述符 fd 的制定事件intpx4_poll(px4_pollfd_struct_t*fds,unsignedintnfds,inttimeout);// fds 要監(jiān)聽的 FD 和事件配置// nfds 要監(jiān)聽的文件描述符數(shù)量即 fds 數(shù)組的有效長度// timeout 阻塞等待的超時時間// 返回值正整數(shù)有事件發(fā)生的 FD 數(shù)量如返回2則表示有2個FD發(fā)生了對應(yīng)的事件需遍歷 fds 檢查 revents0表示超時返回-1發(fā)生錯誤如FD無效、驅(qū)動出錯、信號量操作失敗等orb_copy(ORB_ID(vehicle_acceleration), sensor_sub_fd, accel);從訂閱句柄 sensor_sub_fd 中讀取拷貝最新的消息數(shù)據(jù)到accelintorb_copy(conststructorb_metadata*meta,inthandle,void*buffer)// meta uORB 消息的 “元數(shù)據(jù)指針”// handle uORB 消息的訂閱句柄// buffer 用戶提供的數(shù)據(jù)緩沖區(qū)指針用于存儲讀取到的消息// 返回值成功返回0失敗返回負數(shù)錯誤碼定義在 errno.horb_publish(ORB_ID(vehicle_attitude), att_pub, att);將消息數(shù)據(jù)發(fā)布到 uORB 總線上供所有訂閱該消息的模塊讀取intorb_publish(conststructorb_metadata*meta,orb_advert_thandle,constvoid*data)// meta uORB 消息的 “元數(shù)據(jù)指針”// handle uORB 消息的發(fā)布句柄// data 待發(fā)布的消息數(shù)據(jù)指針指向存儲實際數(shù)據(jù)的結(jié)構(gòu)體// 返回值成功返回0失敗返回負數(shù)錯誤碼