什么是飞行器三自由度

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了什么是飞行器三自由度相关的知识,希望对你有一定的参考价值。

请问什么是自由度(飞行器中),三自由度啥意思,三自由度的分类,还有刘自由度的概念。simulink中飞行器模块中的三自由度的分类是咋分的,每种的三自由度模块的意思,谢谢各位了
就是三自由度不考虑飞行器绕xyz轴的转动,六自由度要考虑,是不?那俯仰通道就要算到六自由度中了?

三自由度 ——质点运动模型 考虑 X Y Z 三方向的位移速度加速度。

任何由人类制造、能飞离地面、在空间飞行并由人来控制的飞行物,称为飞行器。飞行器分为3类:航空器、航天器、火箭和导弹。

飞行器主要有两个用途,侦察和攻击空中单位。如果你的对手有很多的空军,那么用飞行器去攻击它们。可以升级飞行器的攻击力来得到更好的攻击效果。飞行器可以侦察到隐形的单位。

技术指标

高速主轴:负载重量:=5kg, 速率范围:0.1~10000rpm,最大角加速度:1000°/s2; 俯仰轴:旋转范围:±90°,摇摆频率:6Hz(±1°),1Hz(±8°);角位置定位精度:≤±10〞;角位置定位分辨率:≤±3〞;角位置定位分辨率:≤±3〞;方位轴:摇摆范围:±20°;角位置定位精度:±30〞;角位置定位分辨率:≤±3〞。

参考技术A 自由度:描述运动的相互独立的变量数。物理学中的自由度 完全确定一个物体在空间位置所需要的独立坐标数目,叫做这个物体的自由度 如对于质点需要3自由度(X,Y,Z),对于刚体要6个。

三自由度 ——质点运动模型 考虑 X Y Z 三方向的运动

六自由度 ——三维空间刚体运动模型, 除其质心在三轴空间中运动自由度之外,还考虑刚体绕质心的俯仰、横滚、偏航运动,故为六自由度。本回答被提问者和网友采纳
参考技术B 三自由度飞行器模型系统主要包括三自由度飞行器模型系统一台,四个电源模块,一个采集卡,三个编码盘。
三自由度飞行器模型系统是由加拿大Quanser公司提供的实验装置。模型系统有三方面的控制,分别为俯仰角控制,滚转角控制,偏航角控制。
该系统作为一个实验装置,形象直观,结构简单;而作为一个被控对象,它又相当复杂。就其本身而言,是一个高阶次、不稳定、多变量、非线性、强耦合的多输入多输出系统,为了更好地对三自由度飞行器模型系统进行控制,有必要对其设计更有效的控制器。
参考技术C 三自由度 ——质点运动模型 考虑 X Y Z 三方向的位移速度加速度
六自由度 —— 除质点运动外 还考虑姿态运动 角加速度 角速度 姿态角啥的
参考技术D 三自由度 ——质点运动模型 考虑 X Y Z 三方向的位移速度加速度

六自由度 —— 除质点运动外 还考虑姿态运动 角加速度 角速度 姿态角啥的

[原][osgEarth]添加自由飞行漫游器

//头文件里

#define MANIPULATOR_W 0x01
#define MANIPULATOR_A 0x02
#define MANIPULATOR_S 0x04
#define MANIPULATOR_D 0x08
#define MANIPULATOR_R 0x10
#define MANIPULATOR_F 0x20


#define MANIPULATOR_MAX 127

//所有漫游器都必须实现的4个纯虚函数  
        virtual void setByMatrix(const osg::Matrixd& matrix);  //设置相机的位置姿态矩阵  
        virtual void setByInverseMatrix(const osg::Matrixd& matrix) {}  //设置相机的视图矩阵  
        virtual osg::Matrixd getMatrix() const;  //获取相机的姿态矩阵 
        virtual osg::Matrixd getInverseMatrix() const;   //获取相机的视图矩阵 

        //所有操作在这里响应
        virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us);


        void reFreshSawEarth();//在当前经纬度,姿态回正:1.视点向地面 2.头部向正北
        void reFreshSawSkyline(osg::Vec3d eye=osg::Vec3d(0,0,0));//在当前经纬度,头部回正:1.视点中心不变 2.头部向天

        osg::Vec3d   _eye;               //视点位置  
        osg::Quat    _rotate;            //旋转姿态 
        osg::Quat    _rotateNew;            //旋转姿态 
        osg::ref_ptr<osg::Node>  _root;

        osg::observer_ptr<osg::Node> _node;
        osg::observer_ptr<osgEarth::MapNode>   _mapNode;

        osg::ref_ptr<const osgEarth::SpatialReference> _srs;

        float        _speed;                //速度
        float        _speedBase;
        float       _speedMultiple;        //速度倍数
        float        _timerRoll;
        bool        _updateAltitude;
        bool        _updateRollStart;        //更新滚转
        bool        _updateRoll;        //更新滚转
        bool        _openStree;            
        // Internal event stack comprising last two mouse events.
        osg::ref_ptr<const osgGA::GUIEventAdapter> _ga_t1;
        osg::ref_ptr<const osgGA::GUIEventAdapter> _ga_t0;

 

 

//cpp文件
void setByMatrix(const osg::Matrixd& matrix)//设置相机的位置姿态矩阵  
{
    gMinpulatorContgrol = 0;
    _eye = matrix.getTrans();
    osg::Vec3d  v3Eye, v3Center, v3Up;
    v3Eye = _eye;//使用相机实际位置
    osg::Vec3d v3EyeLonLat;
    _srs->transformFromWorld(v3Eye, v3EyeLonLat);
    //先获取当前位置的经纬度,再获取当前正上,正北
    osg::Matrix mRealAttitude;

    if (v3EyeLonLat.z() < 10000)//距离地面1千万米以内需要矫正
        //reFreshSawSkyline();
        _updateRoll = true;
    else
        reFreshSawEarth();
}  

osg::Matrixd getInverseMatrix() const
{
    osg::Matrix mat;
    mat.setRotate(-_rotate);
    mat.preMultTranslate(-_eye);
    return mat;
    //return osg::Matrixd::inverse(getMatrix());
}void setNode(osg::Node* node)
{
    // you can only set the node if it has not already been set, OR if you are setting
    // it to NULL. (So to change it, you must first set it to NULL.) This is to prevent
    // OSG from overwriting the node after you have already set on manually.
    if (node == 0L || !_node.valid())
    {
        _root = node;
        _node = node;
        _mapNode = 0L;
        _srs = 0L;

        established();

        osg::Matrix matrixGood1;
        GeoPoint point1(_srs, 0, 0, 10000.0);
        point1.createLocalToWorld(matrixGood1);

        _eye = matrixGood1.getTrans();

        osg::Vec3d worldup;
        point1.createWorldUpVector(worldup);

        osg::Matrix mat;
        matrixGood1.getRotate().get(mat);
        osg::Vec3d eye, center, up;
        mat.getLookAt(eye, center, up);
        mat.makeLookAt(eye, -worldup, up);

        _rotate = mat.getRotate();

    }
}
void reFreshSawSkyline(osg::Vec3d eye)
{
    osg::Vec3d v3Eye;
    osg::Vec3d v3EyeLonLat;
    v3Eye = _eye;//使用相机实际位置
    
    if (eye != osg::Vec3d(0, 0, 0))
    {
        v3Eye += eye;
    }

    _srs->transformFromWorld(v3Eye, v3EyeLonLat);
    //先获取当前位置的经纬度,再获取当前正上,正北

    if (v3EyeLonLat.z() < 10000)//距离地面1千万米以内需要矫正
    {
            osg::Matrix mRealAttitude;
            GeoPoint gEyeGeo(_srs, v3EyeLonLat.x(), v3EyeLonLat.y(), v3EyeLonLat.z());
            gEyeGeo.createLocalToWorld(mRealAttitude);

            osg::Vec3d v3HorizonUp;//指天向量
            gEyeGeo.createWorldUpVector(v3HorizonUp);

            _rotate.get(mRealAttitude);//要使用当前相机的姿态
            osg::Vec3d  theEye,v3Center, v3Up;
            mRealAttitude.getLookAt(theEye, v3Center, v3Up);//获取新的位置和姿态
            osg::Vec3d v3Direction = v3Center - theEye;
            mRealAttitude.makeLookAt(osg::Vec3d(0, 0, 0), v3Direction, v3HorizonUp);
            _rotate = mRealAttitude.getRotate();
    
    }
    
    //_eye = v3Eye;
}

void  reFreshSawEarth()
{
    osg::Vec3d  v3Eye, v3Center, v3Up;
    v3Eye = _eye;//使用相机实际位置
    osg::Vec3d v3EyeLonLat;
    _srs->transformFromWorld(v3Eye, v3EyeLonLat);
        //先获取当前位置的经纬度,再获取当前正上,正北
        osg::Matrix mRealAttitude;

    if (v3EyeLonLat.z() < 0)//v3EyeLonLat.z()是眼点实际海拔
        v3EyeLonLat.z() = 100;//将海拔0以下的物体拉到海拔100米

    GeoPoint gEyeGeo(_srs, v3EyeLonLat.x(), v3EyeLonLat.y(), v3EyeLonLat.z());
    gEyeGeo.createLocalToWorld(mRealAttitude);

    osg::Vec3d v3HorizonUp;//指天向量
    gEyeGeo.createWorldUpVector(v3HorizonUp);

    _eye = mRealAttitude.getTrans();

    mRealAttitude.getLookAt(v3Eye, v3Center, v3Up);//获取新的位置和姿态

    osg::Matrix mDeviationAttitude;//向北位置偏移0.00001纬度,为了计算正北方向
    GeoPoint gDeviationEyeGeo(_srs, v3EyeLonLat.x(), v3EyeLonLat.y() + 0.00001, v3EyeLonLat.z());
    gDeviationEyeGeo.createLocalToWorld(mDeviationAttitude);
    osg::Vec3d v3DeviationNorthPoint = mDeviationAttitude.getTrans();
    osg::Vec3d v3NorthHeadUp = v3DeviationNorthPoint - v3Eye;
    v3NorthHeadUp.normalize();//指北向量

    if (v3EyeLonLat.y() < 89.99999  && v3EyeLonLat.y() > -90.0)
    {
        mRealAttitude.makeLookAt(osg::Vec3d(0, 0, 0), -v3HorizonUp, v3NorthHeadUp);
    }
    _rotate = mRealAttitude.getRotate();
}

bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us)
{
    bool handled = false;

    switch (ea.getEventType())
    {
    case(osgGA::GUIEventAdapter::FRAME):
    {
        if (gMinpulatorContgrol & MANIPULATOR_MAX)
        {
            osg::Vec3d   v3Direction;         //视点方向  
            osg::Matrix mCameraQuat;
            osg::Vec3d  v3Eye, v3Center, v3Up;
            _rotate.get(mCameraQuat);
            mCameraQuat.getLookAt(v3Eye, v3Center, v3Up);//这里的v3Eye不是实际相机的位置,而是0,0,0
            v3Direction = v3Center - v3Eye;
            v3Direction.normalize();
            /*********************************************************/
            osg::Vec3d RealEye = _eye;
            osg::Vec3d testHight = v3Direction*100;
            double _DvalueHight = 0.0;
            {
                osg::Vec3d testLonLat1, testLonLat2;
                _srs->transformFromWorld(RealEye, testLonLat1);
                RealEye = _eye;
                osg::Vec3d testEye = RealEye + testHight;
                _srs->transformFromWorld(testEye, testLonLat2);
                _DvalueHight = abs(testLonLat2.z() - testLonLat1.z());

                if (_DvalueHight < 10)//趋近水平使用水平方向
                {
                    testLonLat2.z() = testLonLat1.z();
                    _srs->transformToWorld(testLonLat2, testEye);
                    v3Direction = testEye - RealEye;
                    v3Direction.normalize();
                }
            }

            osg::Vec3d v3CrossVector = v3Up^v3Direction;
            v3CrossVector.normalize();

            /*********************************************************/
            //计算地面高度
            osg::Vec3d v3EyeLonLat;
            v3Eye = _eye;
            _srs->transformFromWorld(v3Eye, v3EyeLonLat);
            double mAltitude = VRE_ENGINE.GetToolsFunc()->GetGeoPointAltitude(v3EyeLonLat.x(), v3EyeLonLat.y());
            float height = osg::clampBetween(v3EyeLonLat.z() - mAltitude, 100.0, 1000000.0);
            _speed = height / 200.0;//根据离地面高度计算当前速度值
            RealEye = _eye;
            if (gMinpulatorContgrol & MANIPULATOR_W)
            {
                RealEye += v3Direction * _speed *_speedMultiple * _speedBase;
                _updateAltitude = false;
            }if (gMinpulatorContgrol & MANIPULATOR_A)
            {
                RealEye += v3CrossVector * _speed *_speedMultiple * _speedBase;
                _updateAltitude = false;
            }if (gMinpulatorContgrol & MANIPULATOR_S)
            {
                RealEye -= v3Direction * _speed *_speedMultiple * _speedBase;
                _updateAltitude = false;
            }if (gMinpulatorContgrol & MANIPULATOR_D)
            {
                RealEye -= v3CrossVector * _speed *_speedMultiple * _speedBase;
                _updateAltitude = false;
            }if (gMinpulatorContgrol & MANIPULATOR_R)
            {
                //_eye += v3Up * _speed *_speedMultiple * _speedBase;
                v3EyeLonLat.z() += _speed *_speedMultiple * _speedBase;
                osg::Vec3d newv3Eye;
                _srs->transformToWorld(v3EyeLonLat, newv3Eye);
                RealEye = newv3Eye;
                _updateAltitude = false;
            }if (gMinpulatorContgrol & MANIPULATOR_F)
            {
                //_eye -= v3Up * _speed *_speedMultiple * _speedBase;
                v3EyeLonLat.z() -= _speed *_speedMultiple * _speedBase;
                osg::Vec3d newv3Eye;
                _srs->transformToWorld(v3EyeLonLat, newv3Eye);
                RealEye = newv3Eye;
                _updateAltitude = false;
            }

            _eye = RealEye;
            //reFreshSawSkyline(RealEye);
        }
    
        if (_updateRoll)
        {
            osg::Vec3d v3Eye;
            osg::Vec3d v3EyeLonLat;
            v3Eye = _eye;//使用相机实际位置
            _srs->transformFromWorld(v3Eye, v3EyeLonLat);
            //先获取当前位置的经纬度,再获取当前正上,正北

            if (v3EyeLonLat.z() < 10000)//距离地面1千万米以内需要矫正
            {
                osg::Matrix mRealAttitude;
                GeoPoint gEyeGeo(_srs, v3EyeLonLat.x(), v3EyeLonLat.y(), v3EyeLonLat.z());
                gEyeGeo.createLocalToWorld(mRealAttitude);

                osg::Vec3d v3HorizonUp;//指天向量
                gEyeGeo.createWorldUpVector(v3HorizonUp);

                _rotate.get(mRealAttitude);//要使用当前相机的姿态
                osg::Vec3d  theEye, v3Center, v3Up;
                mRealAttitude.getLookAt(theEye, v3Center, v3Up);//获取新的位置和姿态
                osg::Vec3d v3Direction = v3Center - theEye;
                mRealAttitude.makeLookAt(osg::Vec3d(0, 0, 0), v3Direction, v3HorizonUp);
                _rotateNew = mRealAttitude.getRotate();
                _updateRoll = false;
                _updateRollStart = true;
                _timerRoll = 0.0;
            }
            else
            {
                _updateRoll = false;
            }
        }

        if (_updateRollStart)
        {
            _timerRoll += 0.01;
            if (_timerRoll > 1.0)
            {
                _timerRoll = 1.0;
                _updateRollStart = false;
            }
            _rotate.slerp(_timerRoll, _rotate, _rotateNew);
        }

        if (_updateAltitude)
        {
            //每帧调节高度
            osg::Vec3d newEye = _eye;
            osg::Vec3d v3EyeLonLat;
            _srs->transformFromWorld(newEye, v3EyeLonLat);
            double _mAltitude = v3EyeLonLat.z();
            double mAltitude = VRE_ENGINE.GetToolsFunc()->GetGeoPointAltitude(v3EyeLonLat.x(), v3EyeLonLat.y()) + MANIPULATOR_PERSONVIEWHEIGHT;
            double interprolationAltitude = mAltitude - _mAltitude;
            if (interprolationAltitude > 1)
            {
                interprolationAltitude /= 10.0;
                v3EyeLonLat.z() += interprolationAltitude;
            }
            else if (interprolationAltitude > 0.1)
            {
                v3EyeLonLat.z() += 0.1;
            }
            else
            {
                _updateAltitude = false;
            }
            osg::Vec3d FinalEye;
            _srs->transformToWorld(v3EyeLonLat, FinalEye);
            _eye = FinalEye;
        }
    }break;
    case(osgGA::GUIEventAdapter::PUSH):
    {
    }break;
    case(osgGA::GUIEventAdapter::RELEASE):
    {
        flushMouseEventStack();
    }break;
    case(osgGA::GUIEventAdapter::DRAG):
    {
        if (calcMovement(ea))//根据鼠标在屏幕中的位置调整相机转向
        {
            //reFreshSawSkyline();
            _updateRoll = true;
            us.requestRedraw();
            return true;
        }
    };
    case(osgGA::GUIEventAdapter::SCROLL)://由于已经每帧都调整姿态,所以手动滚动不需要了
    {
        osg::Vec3d   v3Direction;         //视点方向  
        osg::Matrix mCameraQuat;
        osg::Vec3d  v3Eye, v3Center, v3Up;
        _rotate.get(mCameraQuat);
        mCameraQuat.getLookAt(v3Eye, v3Center, v3Up);//这里的v3Eye不是实际相机的位置,而是0,0,0
        v3Direction = v3Center - v3Eye;
        v3Direction.normalize();
        osg::Vec3d v3CrossVector = v3Up^v3Direction;
        v3CrossVector.normalize();
        switch (ea.getScrollingMotion())
        {
        case osgGA::GUIEventAdapter::ScrollingMotion::SCROLL_UP:
        {
            _eye += v3Direction * _speed *_speedMultiple;
            //reFreshSawSkyline();
            _updateRoll = true;
        }break;
        case osgGA::GUIEventAdapter::ScrollingMotion::SCROLL_DOWN:
        {
            _eye -= v3Direction * _speed *_speedMultiple;
            //reFreshSawSkyline();
            _updateRoll = true;
        }break;
        }
        //reFreshSawSkyline();

        return true;
    }break;
    case (osgGA::GUIEventAdapter::KEYDOWN):
    {
        if (ea.getKey() == r || ea.getKey() == R)//往头部前进
        {
            gMinpulatorContgrol |= MANIPULATOR_R;
        }
        if (ea.getKey() == f || ea.getKey() == F)//往尾部后退
        {
            gMinpulatorContgrol |= MANIPULATOR_F;
        }
        if (ea.getKey() == w || ea.getKey() == W || ea.getKey() == osgGA::GUIEventAdapter::KEY_Up)//前进
        {
            gMinpulatorContgrol |= MANIPULATOR_W;
        }
        if (ea.getKey() == s || ea.getKey() == S || ea.getKey() == osgGA::GUIEventAdapter::KEY_Down)//后退
        {
            gMinpulatorContgrol |= MANIPULATOR_S;
        }
        if (ea.getKey() == a || ea.getKey() == A || ea.getKey() == osgGA::GUIEventAdapter::KEY_Left)//左移
        {
            gMinpulatorContgrol |= MANIPULATOR_A;
        }
        if (ea.getKey() == d || ea.getKey() == D || ea.getKey() == osgGA::GUIEventAdapter::KEY_Right)//右移
        {
            gMinpulatorContgrol |= MANIPULATOR_D;
        }
        if (ea.getKey() == - || ea.getKey() == _ || ea.getKey() == osgGA::GUIEventAdapter::KEY_Page_Down)//减10倍移动速度
        {
            _speedBase /= 10.0;
            if (_speedBase < 0.1)
            {
                _speedBase = 0.1;
            }
        }
        if (ea.getKey() == = || ea.getKey() == + || ea.getKey() == osgGA::GUIEventAdapter::KEY_Page_Up)//加10倍移动速度
        {
            _speedBase *= 10.0;
            if (_speedBase > 1000.0)
            {
                _speedBase = 1000.0;
            }
        }

        if (ea.getKey() == h || ea.getKey() == H)//在当前经纬度,姿态回正:1.视点向地面 2.头部向正北
        {
            reFreshSawEarth();
        }
        if (ea.getKey() == g || ea.getKey() == G)//在当前经纬度,头部回正:1.视点中心不变 2.头部向天
        {
            reFreshSawSkyline();
        }
        if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Shift_L || ea.getKey() == osgGA::GUIEventAdapter::KEY_Shift_R)
        {
            _speedMultiple = 10.0;
        }
    }break;
    case (osgGA::GUIEventAdapter::KEYUP):
    {
        if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Shift_L || ea.getKey() == osgGA::GUIEventAdapter::KEY_Shift_R)
        {
            _speedMultiple = 1.0;
        }
        if (ea.getKey() == a || ea.getKey() == A || ea.getKey() == osgGA::GUIEventAdapter::KEY_Left)//左移
        {
            gMinpulatorContgrol &= ~MANIPULATOR_A;
            _updateAltitude = true;
        }
        if (ea.getKey() == d || ea.getKey() == D || ea.getKey() == osgGA::GUIEventAdapter::KEY_Right)//右移
        {
            gMinpulatorContgrol &= ~MANIPULATOR_D;
            _updateAltitude = true;
        }
        if (ea.getKey() == w || ea.getKey() == W || ea.getKey() == osgGA::GUIEventAdapter::KEY_Up)//前进
        {
            gMinpulatorContgrol &= ~MANIPULATOR_W;
            _updateAltitude = true;
        }
        if (ea.getKey() == q || ea.getKey() == Q || ea.getKey() == osgGA::GUIEventAdapter::KEY_Page_Up)//往头部前进
        {
            gMinpulatorContgrol &= ~MANIPULATOR_R;
            _updateAltitude = true;
        }
        if (ea.getKey() == e || ea.getKey() == E || ea.getKey() == osgGA::GUIEventAdapter::KEY_Page_Down)//往尾部后退
        {
            gMinpulatorContgrol &= ~MANIPULATOR_F;
            _updateAltitude = true;
        }
        if (ea.getKey() == s || ea.getKey() == S || ea.getKey() == osgGA::GUIEventAdapter::KEY_Down)//后退
        {
            gMinpulatorContgrol &= ~MANIPULATOR_S;
            _updateAltitude = true;
        }
    }break;
    default:
        break;
    }

    return handled;
}

 

以上是关于什么是飞行器三自由度的主要内容,如果未能解决你的问题,请参考以下文章

无人机开发之三:飞行器入门理论知识

气动干扰下的Hex-Rotor无人飞行器控制器及其飞行实验

[原][osgEarth]添加自由飞行漫游器

[osg][osgEarth][原]基于OE自定义自由飞行漫游器(第二版)

幼儿园宇宙探索:航天飞机有哪些优点?

基于ArduPilot的旋翼式无人机飞行器开发系列(三,四轴无人机的组成)