Warning: Undefined variable $data in /data/www/wwwroot/woiwrj/woiwrj/wp-content/themes/justnews/themer/functions/shortcodes-render.php on line 89
Warning: Undefined variable $data in /data/www/wwwroot/woiwrj/woiwrj/wp-content/themes/justnews/themer/functions/shortcodes-render.php on line 89
Warning: Undefined variable $data in /data/www/wwwroot/woiwrj/woiwrj/wp-content/themes/justnews/themer/functions/shortcodes-render.php on line 89
Warning: Undefined variable $data in /data/www/wwwroot/woiwrj/woiwrj/wp-content/themes/justnews/themer/functions/shortcodes-render.php on line 89
Warning: Undefined variable $data in /data/www/wwwroot/woiwrj/woiwrj/wp-content/themes/justnews/themer/functions/shortcodes-render.php on line 89
Warning: Undefined variable $data in /data/www/wwwroot/woiwrj/woiwrj/wp-content/themes/justnews/themer/functions/shortcodes-render.php on line 89
Warning: Undefined variable $data in /data/www/wwwroot/woiwrj/woiwrj/wp-content/themes/justnews/themer/functions/shortcodes-render.php on line 89
Warning: Undefined variable $data in /data/www/wwwroot/woiwrj/woiwrj/wp-content/themes/justnews/themer/functions/shortcodes-render.php on line 89
Warning: Undefined variable $data in /data/www/wwwroot/woiwrj/woiwrj/wp-content/themes/justnews/themer/functions/shortcodes-render.php on line 89
Warning: Undefined variable $data in /data/www/wwwroot/woiwrj/woiwrj/wp-content/themes/justnews/themer/functions/shortcodes-render.php on line 89
Warning: Undefined variable $data in /data/www/wwwroot/woiwrj/woiwrj/wp-content/themes/justnews/themer/functions/shortcodes-render.php on line 89
Warning: Undefined variable $data in /data/www/wwwroot/woiwrj/woiwrj/wp-content/themes/justnews/themer/functions/shortcodes-render.php on line 89
Warning: Undefined variable $data in /data/www/wwwroot/woiwrj/woiwrj/wp-content/themes/justnews/themer/functions/shortcodes-render.php on line 89
今天來聊一聊minimosd無人機協(xié)議。Osd的全稱是on-screen display,指在屏幕視頻之上疊加數(shù)據(jù),相信每一個使用apm或者pix做飛行控制器的人都多少與osd打過交道。目前市面所有的飛控osd模塊都是起源于google上的minimosd項目。
該項目版本截止于12年的2.0。其硬件解決方案是采用atmega328芯片作為主控,配置相當于arduino nano,具有32kb的flash,2kb的sram以及1kb的eeprom;同時采用7456作為字符疊加芯片,7456可以存儲256個字符,針對pal或者ntsc信號完成字符疊加。在軟件方面,遵從mavlink協(xié)議,從串口獲取封裝為該協(xié)議的飛行數(shù)據(jù),顯示在視頻之上,同時具有桌面配置程序,支持用戶配置顯示信息的內(nèi)容與風格。在minimosd2.0版本的基礎之上,全球范圍內(nèi)出現(xiàn)了若干分支版本,其中比較著名的是托管在github上的minimosd-extra 2.4(https://github.com/diydrones/MinimOSD-Extra/wiki), 該版本在原版基礎上擴展對mavlink傳遞信息的支持,可以顯示更多的飛行數(shù)據(jù),并且具備了簡單的飛行統(tǒng)計功能,還改進了osd顯示方案的切換方式。
在此之外,也流傳著一批針對國內(nèi)用戶的中文版osd固件,基本上都是基于minimosd-extra進行了簡單改造。而杭州的playuav則大膽的對osd體系結構進行了改進,徹底改變了osd硬件架構,做出了一些很有新意的osd嘗試(https://github.com/PlayUAV/)。
作為一個源碼解析類的專題,下面我們以google上的項目minimosd-2.0源碼為基礎,來進一步了解minimosd的程序語言。
Minimosd源碼分為三個部分,分別是osd功能固件ArduCam_Osd;配套庫libraries以及osd的桌面配置工具OSD_Config。我們主要研讀的代碼是ArduCam_OSD,是燒錄到osd片子上的主要功能代碼。
ArduCam工程的主要功能文件包括兩個頭文件:OSD_Vars.h,OSD_Config.h以及三個源碼定義文件ArduCAM_osd.ion,OSD_Panels.ino,MAVLink.ino。
OSD_Vars.h中定義的變量儲存了從mavlink協(xié)議獲取的飛行數(shù)據(jù),這些飛行數(shù)據(jù)被解析后,保存在運行時內(nèi)存sram中。
OSD_Config.h則負責與eeprom打交道,定義了配置信息在eeprom中的保存位置,便于minimosd啟動后,從eeprom讀取用戶配置信息。
ArduCAM_osd.ino是minimosd的程序入口點,是整個程序的骨架。
OSD_Panels.ino是具體的繪制功能,每一幀視頻,都有這些功能,將飛行器信息繪制到視頻之上。
MavLink.ino則是用于對mavlink協(xié)議的解析,將收到的數(shù)據(jù)包按照mavlink協(xié)議解析,解析成功后將數(shù)據(jù)儲存在ODS_Vars.h中定義的變量中。
整個minimosd的程序流程非常簡單,如下圖所示
在minimosd通電啟動后,首先調(diào)用到Setup入口函數(shù),實現(xiàn)如下流程。
1.初始化mavlink,設置了與飛控連接的串口波特率以及端口號
Serial.begin(TELEMETRY_SPEED);// setup mavlink port
mavlink_comm_0_port = &Serial;
然后向飛控發(fā)送數(shù)據(jù)請求,osd需要如下飛行數(shù)據(jù)
MAV_DATA_STREAM_EXTENDED_STATUS,
MAV_DATA_STREAM_RC_CHANNELS,
MAV_DATA_STREAM_POSITION,
MAV_DATA_STREAM_EXTRA1,
</span>MAV_DATA_STREAM_EXTRA2
2.初始化7456,設置7456通信的spi端口,并且激活7456
pinMode(MAX7456_SELECT, OUTPUT); // OSD CS
digitalWrite(MAX7456_SELECT, HIGH); // unplug OSD
3.讀取eeprom設置,OSD_Config.h中記錄了不同的設置信息在eeprom中的存儲位置,在這里逐次讀取,如:
//****** First set of 8 Panels ******
uint16_t offset = OffsetBITpanel * panel;
setBit(panA_REG, Cen_BIT, readEEPROM(panCenter_en_ADDR + offset));
panCenter_XY[0]=readEEPROM(panCenter_x_ADDR + offset);
panCenter_XY[1]=checkPAL(readEEPROM(panCenter_y_ADDR + offset));
這里要說一下minimosd中的panel結構,minimosd中設計了4組,每組8個,共32個數(shù)據(jù)槽位,每個槽位分別對應于需要顯示的一種飛行數(shù)據(jù)。針對每個槽位,可以開啟或者關閉顯示,亦可以設置該槽位在屏幕上的顯示位置(x,y坐標)。對于上述的32組槽位設置,minimosd支持兩種方案,所以放到一個長度為2的數(shù)組中進行管理 。
下述代碼是每個槽位是否顯示的變量結構,每組8個槽位的1或者0正好對應于一個byte數(shù)據(jù)類型,因為有兩套顯示方案,所以每組都是一個長度為2的byte數(shù)組
// Panel BIT registers
byte panA_REG[npanels] = {0b00000000};
byte panB_REG[npanels] = {0b00000000};
byte panC_REG[npanels] = {0b00000000};
byte panD_REG[npanels] = {0b00000000}
下述代碼是槽位顯示位置的變量結構,x和y坐標分別用byte來存儲。同樣,都可以應對兩套顯示方案。
// First 8 panels and their X,Y coordinate holders
byte panCenter_XY[2][npanels]; // = { 13,7,0 };
byte panPitch_XY[2][npanels]; // = { 11,1 };
byte panRoll_XY[2][npanels]; // = { 23,7 };
byte panBatt_A_XY[2][npanels]; // = { 23,1 };
byte panGPSats_XY[2][npanels]; // = { 2,12 };
byte panGPL_XY[2][npanels]; // = { 2,11 };
byte panGPS_XY[2][npanels]; // = { 2,13 };
byte panBatteryPercent_XY[2][npanels];
// ……..
4.啟動loop循環(huán),無更多細節(jié)。
通電后,minimosd完成Setup中的所有功能,便進入了一個周而復始的循環(huán)工作過程,不斷的調(diào)用Loop函數(shù),而每個loop循環(huán),則執(zhí)行如下函數(shù):
1.獲取mavlink數(shù)據(jù).根據(jù)mavlink的msgid,獲知數(shù)據(jù)類型,后分別調(diào)用mavlink庫中的函數(shù)對數(shù)據(jù)包進行解析,存儲到變量中。
if(mavlink_parse_char(MAVLINK_COMM_0, c, &msg, &status)) {
mavlink_active = 1;
//handle msg
switch(msg.msgid) {
case MAVLINK_MSG_ID_HEARTBEAT:
case MAVLINK_MSG_ID_SYS_STATUS:
osd_vbat_A = (mavlink_msg_sys_status_get_voltage_battery(&msg) / 1000.0f); //Battery voltage, in millivolts (1 = 1 millivolt)
osd_curr_A = mavlink_msg_sys_status_get_current_battery(&msg); //Battery current, in 10*milliamperes (1 = 10 milliampere)
osd_battery_remaining_A = mavlink_msg_sys_status_get_battery_remaining(&msg); //Remaining battery energy: (0%: 0, 100%: 100)
..
case MAVLINK_MSG_ID_GPS_RAW_INT:
2.字符繪制,這是osd的核心功能,針對允許顯示的飛行數(shù)據(jù),調(diào)用繪制該數(shù)據(jù)的函數(shù)
if(ISd(panel,Warn_BIT)) panWarn(panWarn_XY[0], panWarn_XY[1]); // this must be here so warnings are always checked
//Testing bits from 8 bit register A
if(ISa(panel,Cen_BIT)) panCenter(panCenter_XY[0], panCenter_XY[1]); //4×2
if(ISa(panel,Pit_BIT)) panPitch(panPitch_XY[0], panPitch_XY[1]); //5×1
if(ISa(panel,Rol_BIT)) panRoll(panRoll_XY[0], panRoll_XY[1]);
if(ISa(panel,BatA_BIT)) panBatt_A(panBatt_A_XY[0], panBatt_A_XY[1]); //7×1
//…………………….
//…………………….
我們以繪制電池電量panBatt_A為例,該函數(shù)代碼如下:
void panBatt_A(int first_col, int first_line){
osd.setPanel(first_col, first_line);
osd.openPanel;
osd.printf(“%c%5.2f%c”, 0xE2, (double)osd_vbat_A, 0x8E);
osd.closePanel;
}
其中,osd.setPanel函數(shù)是7456提供的開發(fā)接口,設置當前要繪制字符的位置。
Osd.printf函數(shù)類似于標準c++的printf,是向7456當前的位置輸出字符。在上述代碼中,在eeprom讀出的屏幕位置,繪制了從mavlink協(xié)議獲取的osd_vbat_A變量的值。
這里需要注意到的是,7456字符疊加器內(nèi)部存儲了256種不同的字符圖標,正好對應了char類型的取值范圍,可以通過MAX7456Charwizard.jar編輯相應的圖標,大家使用的中文版osd,也就是這樣制作出來的,僅僅將用到的中文畫成了圖標,而并不是支持所有的中文字庫。
上述是osd的功能性代碼的簡單介紹,希望可以對大家有所幫助。
最后給大家留一個思考題。我們可以看到minimosd的功能非常簡單,僅僅解析了mavlink4到5類數(shù)據(jù)包,存儲其中32種飛行數(shù)據(jù),但是,大家可以嘗試看看代碼中對于顯示槽位相關的儲存結構,十分的晦澀難懂。那么,請大家思考一下,為什么minimosd代碼功能如此簡單,卻動用了天書一般的數(shù)據(jù)結構來實現(xiàn)?
版權聲明:本文內(nèi)容由互聯(lián)網(wǎng)用戶自發(fā)貢獻,該文觀點僅代表作者本人。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如發(fā)現(xiàn)本站有涉嫌抄襲侵權/違法違規(guī)的內(nèi)容, 請發(fā)送郵件至2161241530@qq.com 舉報,一經(jīng)查實,本站將立刻刪除。如若轉載,請注明出處:http://m.sdanke.com/wurenjibaike/djiwurenzhishi/8338/