Qt 通过UI界面显示飞机姿态仪(Attitude Director Indicator)数据及仪表盘图像


前言

通过Qt做一个UI界面显示飞控仪表数据情况,实时显示当前滚转角及俯仰角数据,并且绘制出仪表盘。本项目参考此篇博客https://blog.csdn.net/goldenhawking/article/details/78817426


效果

实验效果如下图所示,姿态仪显示当前的滚转角及俯仰角的数据(根据系统时间换算的随机数据),并根据其数据绘制仪表盘。
在这里插入图片描述


资源下载

本次实验全部代码请至https://download.csdn.net/download/wang_chao118/86458565下载。


核心代码

本项目工程文件夹目录如下图所示
在这里插入图片描述

定义了一个派生于QGraphicsView的Adi类,封装姿态仪所需相关属性及方法;LayoutSquare类派生于QLayout类,用于实现保持图片的纵横比例;WidgetADI类作为显示Adi的载体,封装了设置Adi类中各个变量的方法;Widget类为整体的底层显示界面。

Adi.hpp

#ifndef __qfi_Adi_H__
#define __qfi_Adi_H__

#include <QGraphicsView>

class QWidget;
class QResizeEvent;
class QGraphicsScene;
class QGraphicsSvgItem;

namespace qfi {

//---------------------------------------------------
// Class: Adi
// Description: Attitude Director Indicator
//---------------------------------------------------
class Adi : public QGraphicsView
{
    Q_OBJECT

public:
    Adi(QWidget* parent = nullptr);
    virtual ~Adi();

    // reinitiates widget
    void reinit();

    // refreshes (redraws) widget
    void update();

    void setRoll(const float);
    void setPitch(const float);

protected:
    void resizeEvent(QResizeEvent*);

private:
    void init();
    void reset();
    void updateView();

    QGraphicsScene* m_scene{};

    QGraphicsSvgItem* m_itemBack{};
    QGraphicsSvgItem* m_itemFace{};
    QGraphicsSvgItem* m_itemRing{};
    QGraphicsSvgItem* m_itemCase{};

    float m_roll{};
    float m_pitch{};

    float m_faceDeltaX_new{};
    float m_faceDeltaX_old{};
    float m_faceDeltaY_new{};
    float m_faceDeltaY_old{};

    float m_scaleX{1.0f};
    float m_scaleY{1.0f};

    const int m_originalHeight{240};
    const int m_originalWidth{240};

    const float m_originalPixPerDeg{1.7f};

    QPointF m_originalAdiCtr{120.0f, 120.0f};

    const int m_backZ{-30};
    const int m_faceZ{-20};
    const int m_ringZ{-10};
    const int m_caseZ{10};
};

}

#endif

#endif // HEROPLANE_H

Adi.cpp


#include "Adi.hpp"
#include <QGraphicsSvgItem>
#include <cmath>

#define M_PI       3.14159265358979323846   // pi

namespace qfi {

Adi::Adi(QWidget* parent) : QGraphicsView (parent)
{
    m_scene = new QGraphicsScene( this );
    setScene( m_scene );
    m_scene->clear();
    init();
}

Adi::~Adi()
{
    if (m_scene) {
        m_scene->clear();
        delete m_scene;
        m_scene = nullptr;
    }

    reset();
}

void Adi::reinit()
{
    if (m_scene) {
        m_scene->clear();
        init();
    }
}

void Adi::update()
{
    updateView();

    m_faceDeltaX_old  = m_faceDeltaX_new;
    m_faceDeltaY_old  = m_faceDeltaY_new;
}

void Adi::setRoll(const float roll)
{
    m_roll = roll;

    if ( m_roll < -180.0f ) m_roll = -180.0f;
    if ( m_roll >  180.0f ) m_roll =  180.0f;
}

void Adi::setPitch(const float pitch)
{
    m_pitch = pitch;

    if ( m_pitch < -25.0f ) m_pitch = -25.0f;
    if ( m_pitch >  25.0f ) m_pitch =  25.0f;
}

void Adi::resizeEvent(QResizeEvent* event)
{
    QGraphicsView::resizeEvent( event );
    reinit();
}

void Adi::init()
{
    m_scaleX = static_cast<float>(width())  / static_cast<float>(m_originalWidth);
    m_scaleY = static_cast<float>(height()) / static_cast<float>(m_originalHeight);

    reset();

    m_itemBack = new QGraphicsSvgItem( ":/qfi/images/adi/adi_back.svg" );
    m_itemBack->setCacheMode( QGraphicsItem::NoCache );
    m_itemBack->setZValue( m_backZ );
    m_itemBack->setTransform( QTransform::fromScale( m_scaleX, m_scaleY ), true );
    m_itemBack->setTransformOriginPoint( m_originalAdiCtr );
    m_scene->addItem( m_itemBack );

    m_itemFace = new QGraphicsSvgItem( ":/qfi/images/adi/adi_face.svg" );
    m_itemFace->setCacheMode( QGraphicsItem::NoCache );
    m_itemFace->setZValue( m_faceZ );
    m_itemFace->setTransform( QTransform::fromScale( m_scaleX, m_scaleY ), true );
    m_itemFace->setTransformOriginPoint( m_originalAdiCtr );
    m_scene->addItem( m_itemFace );

    m_itemRing = new QGraphicsSvgItem( ":/qfi/images/adi/adi_ring.svg" );
    m_itemRing->setCacheMode( QGraphicsItem::NoCache );
    m_itemRing->setZValue( m_ringZ );
    m_itemRing->setTransform( QTransform::fromScale( m_scaleX, m_scaleY ), true );
    m_itemRing->setTransformOriginPoint( m_originalAdiCtr );
    m_scene->addItem( m_itemRing );

    m_itemCase = new QGraphicsSvgItem( ":/qfi/images/adi/adi_case.svg" );
    m_itemCase->setCacheMode( QGraphicsItem::NoCache );
    m_itemCase->setZValue( m_caseZ );
    m_itemCase->setTransform( QTransform::fromScale( m_scaleX, m_scaleY ), true );
    m_scene->addItem( m_itemCase );

    centerOn( width() / 2.0f , height() / 2.0f );

    updateView();
}

void Adi::reset()
{
    m_itemBack = nullptr;
    m_itemFace = nullptr;
    m_itemRing = nullptr;
    m_itemCase = nullptr;

    m_roll  = 0.0f;
    m_pitch = 0.0f;

    m_faceDeltaX_new = 0.0f;
    m_faceDeltaX_old = 0.0f;
    m_faceDeltaY_new = 0.0f;
    m_faceDeltaY_old = 0.0f;
}

void Adi::updateView()
{
    m_scaleX = static_cast<float>(width())  / static_cast<float>(m_originalWidth);
    m_scaleY = static_cast<float>(height()) / static_cast<float>(m_originalHeight);

    m_itemBack->setRotation(-m_roll);
    m_itemFace->setRotation(-m_roll);
    m_itemRing->setRotation(-m_roll);

    const float roll_rad{static_cast<float>(M_PI * m_roll / 180.0)};
    const float delta{static_cast<float>(m_originalPixPerDeg * m_pitch)};

    m_faceDeltaX_new = m_scaleX * delta * std::sin( roll_rad );
    m_faceDeltaY_new = m_scaleY * delta * std::cos( roll_rad );

    m_itemFace->moveBy( m_faceDeltaX_new - m_faceDeltaX_old, m_faceDeltaY_new - m_faceDeltaY_old );

    m_scene->update();
}

}


整体工程文件夹内内容见资源下载

资源下载

本次实验全部代码请至https://download.csdn.net/download/wang_chao118/86458565下载。

  • 1
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 11
    评论
以下是NSGA-II算法的Matlab代码示例: ``` % NSGA-II algorithm implementation in Matlab % Author: https://www.github.com/rafitc % Adapted from: https://www.mathworks.com/matlabcentral/fileexchange/19915-nsga-ii-a-multi-objective-optimization-algorithm % Problem definition n = 10; % Number of decision variables m = 2; % Number of objectives lb = zeros(1,n); % Lower bounds ub = ones(1,n); % Upper bounds f1 = @(x) x(1); % Objective 1 f2 = @(x) (1+x(2))/x(1); % Objective 2 f = {f1,f2}; % NSGA-II parameters popSize = 100; % Population size maxGen = 50; % Maximum number of generations pc = 0.8; % Crossover probability nc = 2; % Number of children per crossover pm = 1/n; % Mutation probability nm = round(pm*popSize*n); % Number of mutants eta = 20; % Crossover and mutation distribution index alpha = 0.5; % Crowding distance parameter % Initialize population popDec = lhsdesign(popSize,n); popObj = evaluatePopulation(popDec,f); % NSGA-II main loop for iGen = 1:maxGen % Non-dominated sorting fronts = nonDominatedSorting(popObj); % Crowding distance assignment dist = crowdingDistanceAssignment(popObj,fronts,alpha); % Select parents parents = tournamentSelection(popObj,fronts,dist); % Generate offspring offDec = sbxCrossover(parents,pc,nc,lb,ub,eta); offDec = polynomialMutation(offDec,pm,lb,ub,eta); % Evaluate offspring offObj = evaluatePopulation(offDec,f); % Merge parent and offspring populations dec = [popDec;offDec]; obj = [popObj;offObj]; % Non-dominated sorting of merged population fronts = nonDominatedSorting(obj); % Crowding distance assignment of merged population dist = crowdingDistanceAssignment(obj,fronts,alpha); % Select new population popDec = []; popObj = []; iFront = 1; while(length(popObj) + length(fronts{iFront}) <= popSize) % Fill up population with fronts popDec = [popDec;dec(fronts{iFront},:)]; popObj = [popObj;obj(fronts{iFront},:)]; iFront = iFront + 1; end if(length(popObj) < popSize) % Fill up remaining population with individuals from last front lastFront = fronts{iFront}; [~,rank] = sort(dist(lastFront),'descend'); popDec = [popDec;dec(lastFront(rank(1:popSize-length(popObj))),:)]; popObj = [popObj;obj(lastFront(rank(1:popSize-length(popObj))),:)]; end % Display progress disp(['Generation ' num2str(iGen) ': hypervolume = ' num2str(hypervolume(popObj,[0 0]))]) end % Plot final population scatter(popObj(:,1),popObj(:,2),20,'k','filled') xlabel('Objective 1') ylabel('Objective 2') title('NSGA-II') ``` 注意,此代码中的许多函数都需要自己实现。但是,这个代码示例可以让您了解NSGA-II算法实现的主要步骤。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wang_chao118

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值