ArduPilot开源代码之AP_OSD_SITL
ArduPilot开源代码之AP_OSD_SITL
- 1. 源由
- 2. 结构设计
- 2.1 成员变量
- 2.2 OSD 符号
- 2.3 图形线程
- 3. 接口设计
- 3.1 一次性接口
- 3.1.1 init
- 3.1.2 osd_thread_run_once
- 3.1.3 init_symbol_set
- 3.1.4 probe
- 3.2 基本操作
- 3.2.1 write
- 3.2.2 flush
- 3.2.3 clear
- 3.3 功能函数
- 3.3.1 is_compatible_with_backend_type
- 3.3.2 get_backend_type
- 3.3.3 get_aspect_ratio_correction
- 4. 总结
- 5. 参考资料
1. 源由
前面讨论了
- ArduPilot开源代码之AP_OSD
- ArduPilot开源代码之AP_OSD_Backend
本章将针对具体的AP_OSD_SITL
类进行研讨。
2. 结构设计
2.1 成员变量
新增的变量主要用于模拟器的仿真OSD显示。
sf::RenderWindow *w;
sf::Texture font[256];
uint8_t last_font;
// setup to match MAX7456 layout
static const uint8_t char_width = 12;
static const uint8_t char_height = 18;
uint8_t video_lines;
uint8_t video_cols;
static const uint8_t char_spacing = 0;
// scaling factor to make it easier to read
static const uint8_t char_scale = 2;
uint8_t *buffer;
pthread_t thread;
HAL_Semaphore mutex;
uint32_t counter;
uint32_t last_counter;
2.2 OSD 符号
无自定义,将会保持与 AP_OSD_Backend
一致。
2.3 图形线程
- void update_thread()
- static void *update_thread_start(void *obj)
// main loop of graphics thread
void AP_OSD_SITL::update_thread(void)
{
load_font();
{
WITH_SEMAPHORE(AP::notify().sf_window_mutex);
w = NEW_NOTHROW sf::RenderWindow(sf::VideoMode(video_cols*(char_width+char_spacing)*char_scale,
video_lines*(char_height+char_spacing)*char_scale),
"OSD");
}
if (!w) {
AP_HAL::panic("Unable to create OSD window");
}
while (true) {
{
WITH_SEMAPHORE(AP::notify().sf_window_mutex);
sf::Event event;
while (w->pollEvent(event)) {
if (event.type == sf::Event::Closed) {
w->close();
}
}
if (!w->isOpen()) {
break;
}
if (counter != last_counter) {
last_counter = counter;
uint8_t buffer2[video_lines][video_cols];
{
WITH_SEMAPHORE(mutex);
memcpy(buffer2, buffer, sizeof(buffer2));
}
w->clear();
for (uint8_t y=0; y<video_lines; y++) {
for (uint8_t x=0; x<video_cols; x++) {
uint16_t px = x * (char_width+char_spacing) * char_scale;
uint16_t py = y * (char_height+char_spacing) * char_scale;
sf::Sprite s;
uint8_t c = buffer2[y][x];
s.setTexture(font[c]);
s.setPosition(sf::Vector2f(px, py));
s.scale(sf::Vector2f(char_scale,char_scale));
w->draw(s);
}
}
w->display();
if (last_font != get_font_num()) {
load_font();
}
}
}
usleep(10000);
}
}
3. 接口设计
3.1 一次性接口
3.1.1 init
创建图形线程。
// initialise backend
bool AP_OSD_SITL::init(void)
{
pthread_create(&thread, NULL, update_thread_start, this);
return true;
}
3.1.2 osd_thread_run_once
无,使用AP_OSD_Backend::osd_thread_run_once
3.1.3 init_symbol_set
无,使用AP_OSD_Backend::init_symbol_set
3.1.4 probe
最初的初始化,直接在AP_OSD::init_backend
中进行,详见:ArduPilot开源代码之AP_OSD
AP_OSD_Backend *AP_OSD_SITL::probe(AP_OSD &osd)
{
AP_OSD_SITL *backend = NEW_NOTHROW AP_OSD_SITL(osd);
if (!backend) {
return nullptr;
}
if (!backend->init()) {
delete backend;
return nullptr;
}
return backend;
}
3.2 基本操作
3.2.1 write
直接写入界面缓存中。
void AP_OSD_SITL::write(uint8_t x, uint8_t y, const char* text)
{
if (y >= video_lines || text == nullptr) {
return;
}
WITH_SEMAPHORE(mutex);
while ((x < video_cols) && (*text != 0)) {
getbuffer(buffer, y, x) = *text;
++text;
++x;
}
}
3.2.2 flush
只有当counter
发生变化时,图形线程才会刷新OSD。
void AP_OSD_SITL::flush(void)
{
counter++;
}
3.2.3 clear
缓存清零,相当于OSD清空。
void AP_OSD_SITL::clear(void)
{
AP_OSD_Backend::clear();
WITH_SEMAPHORE(mutex);
memset(buffer, 0, video_cols*video_lines);
}
3.3 功能函数
3.3.1 is_compatible_with_backend_type
- 不兼容:OSD_MAX7456/OSD_SITL
- 兼容:OSD_MSP/OSD_MSP_DISPLAYPORT
bool is_compatible_with_backend_type(AP_OSD::osd_types type) const override {
switch(type) {
case AP_OSD::osd_types::OSD_MAX7456:
case AP_OSD::osd_types::OSD_SITL:
return false;
case AP_OSD::osd_types::OSD_NONE:
case AP_OSD::osd_types::OSD_TXONLY:
case AP_OSD::osd_types::OSD_MSP:
case AP_OSD::osd_types::OSD_MSP_DISPLAYPORT:
return true;
}
return false;
}
3.3.2 get_backend_type
AP_OSD::osd_types get_backend_type() const override {
return AP_OSD::osd_types::OSD_SITL;
}
3.3.3 get_aspect_ratio_correction
无,使用AP_OSD_Backend::get_aspect_ratio_correction
4. 总结
AP_OSD_SITL
模拟器上的OSD显示,因此与硬件MAX7456不兼容,与纯软类OSD协议兼容。
5. 参考资料
【1】ArduPilot开源飞控系统之简单介绍
【2】ArduPilot之开源代码Task介绍
【3】ArduPilot飞控启动&运行过程简介
【4】ArduPilot之开源代码Library&Sketches设计
【5】ArduPilot之开源代码Sensor Drivers设计
【6】ArduPilot开源代码之AP_OSD_Backend