ArduPilot开源代码之AP_OSD_SITL

1. 源由

前面讨论了

本章将针对具体的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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值