ORB-SLAM2从理论到代码实现(六):Tracking程序详解(上)

1. Tracking框架

Tracking线程流程框图:

各流程对应的主要函数

2. Tracking整体流程图

上面这张图把Tracking.cc讲的特别明白。

tracking线程在获取图像数据后,会传给函数GrabImageStereo、GrabImageRGBD或GrabImageMonocular进行预处理,这里以GrabImageMonocular为例。

GrabImageMonocular(const cv::Mat &im, const double &timestamp)

函数功能

1. 将图像转为mImGray并初始化mCurrentFrame;

2. 进行tracking过程,输出世界坐标系到该帧相机坐标系的变换矩阵

im输入图像
timestamp时间戳
cv::Mat Tracking::GrabImageMonocular(const cv::Mat &im, const double &timestamp)
 
{
    mImGray = im;//读取图像
    // 步骤1:将RGB或RGBA图像转为灰度图像
    if(mImGray.channels()==3)
    {
        if(mbRGB)
            cvtColor(mImGray,mImGray,CV_RGB2GRAY);
        else
            cvtColor(mImGray,mImGray,CV_BGR2GRAY);
    }
    else if(mImGray.channels()==4)
    {
        if(mbRGB)
            cvtColor(mImGray,mImGray,CV_RGBA2GRAY);
        else
            cvtColor(mImGray,mImGray,CV_BGRA2GRAY);
    }
    // 步骤2:构造Frame
    if(mState==NOT_INITIALIZED || mState==NO_IMAGES_YET)// 没有成功初始化的前一个状态就是NO_IMAGES_YET
        mCurrentFrame = Frame(mImGray,timestamp,mpIniORBextractor,mpORBVocabulary,mK,mDistCoef,mbf,mThDepth);
    else
        mCurrentFrame = Frame(mImGray,timestamp,mpORBextractorLeft,mpORBVocabulary,mK,mDistCoef,mbf,mThDepth);
    // 步骤3:跟踪
    Track();
    return mCurrentFrame.mTcw.clone();
}

数据,流到Track(),由于代码超长,分几段粘贴注释。 

void Tracking::Track()

步骤

1. 判断tracking状态:如果是未初始化(NOT_INITIALIZED),则对单目和非单目分别执行MonocularInitialization()、StereoInitialization()进行初始化,并更新地图视图。

2.对于初始化成功的,接下来进行跟踪ORB-SLAM中关于跟踪状态有两种选择(由mbOnlyTracking判断)

(1)只进行跟踪不建图

(2)同时跟踪和建图:

初始化之后ORB-SLAM有三种跟踪模型可供选择

a.TrackWithMotionModel(); 运动模型:根据运动模型估计当前帧位姿——根据匀速运动模型对上一帧的地图点进行跟踪——优化位姿。

b.TrackReferenceKeyFrame(); 关键帧模型:BoW搜索当前帧与参考帧的匹配点——将上一帧的位姿作为当前帧的初始值——通过优化3D-2D的重投影误差来获得位姿。

c.Relocalization();重定位模型:计算当前帧的BoW——检测满足重定位条件的候选帧——通过BoW搜索当前帧与候选帧的匹配点——大于15个点就进行PnP位姿估计——优化。

这三个模型的选择方法:

首先假设相机恒速(即Rt和上一帧相同),然后计算匹配点数(如果匹配足够多则认为跟踪成功),如果匹配点数目较少,说明恒速模型失效,则选择参考帧模型(即特征匹配,PnP求解),如果参考帧模型同样不能进行跟踪,说明两帧键没有相关性,这时需要进行重定位,即和已经产生的关键帧中进行匹配(看看是否到了之前已经到过的地方)确定相机位姿,如果重定位仍然不能成功,则说明跟踪彻底丢失,要么等待相机回转,要不进行重置。

2.1. 初始化部分

void Tracking::Track()
{
    // track包含两部分:估计运动、跟踪局部地图
    // mState为tracking的状态
    // SYSTME_NOT_READY, NO_IMAGE_YET, NOT_INITIALIZED, OK, LOST
    // 如果图像复位过、或者第一次运行,则为NO_IMAGE_YET状态
    if(mState==NO_IMAGES_YET)
    {
        mState = NOT_INITIALIZED;
    }
 
    // mLastProcessedState存储了Tracking最新的状态,用于FrameDrawer中的绘制
    mLastProcessedState=mState;
    // Get Map Mutex -> Map cannot be changed
    unique_lock<mutex> lock(mpMap->mMutexMapUpdate);
    // 步骤1:初始化
    if(mState==NOT_INITIALIZED)//判断是否初始化
    {
        if(mSensor==System::STEREO || mSensor==System::RGBD)//双目或深度相机
            StereoInitialization();//双目初始化
        else
            MonocularInitialization();//单目初始化
        mpFrameDrawer->Update(this);
        if(mState!=OK)
            return;
    }
}

2.3. 跟踪

2.3.1. 跟踪上一帧或者参考帧或者重定位

else// 步骤2:跟踪
    {
        // System is initialized. Track Frame.系统完成初始化,跟踪帧
        // bOK为临时变量,用于表示每个函数是否执行成功
        bool bOK;
        // Initial camera pose estimation using motion model or relocalization (if tracking is lost)运用运动模型或重定位初始化相机位姿估计
        // 在viewer中有个开关menuLocalizationMode,有它控制是否ActivateLocalizationMode,并最终管控mbOnlyTracking
        // mbOnlyTracking等于false表示正常VO模式(有地图更新),mbOnlyTracking等于true表示用户手动选择定位模式
        if(!mbOnlyTracking)
        {
            // Local Mapping is activated. This is the normal behaviour, unless
            // you explicitly activate the "only tracking" mode.
            // 正常初始化成功
            if(mState==OK)
            {
                // Local Mapping might have changed some MapPoints tracked in last frame
                // 检查并更新上一帧被替换的MapPoints
                // 更新Fuse函数和SearchAndFuse函数替换的MapPoints
                CheckReplacedInLastFrame();
                // 步骤2.1:跟踪上一帧或者参考帧或者重定位
                // 运动模型是空的或刚完成重定位
                // mCurrentFrame.mnId<mnLastRelocFrameId+2表示刚重定位少于两帧
                // 应该只要mVelocity不为空,就优先选择TrackWithMotionModel
                // mnLastRelocFrameId上一次重定位的那一帧
                if(mVelocity.empty() || mCurrentFrame.mnId<mnLastRelocFrameId+2)
                {
                    // 将上一帧的位姿作为当前帧的初始位姿
                    // 通过BoW的方式在参考帧中找当前帧特征点的匹配点
                    // 优化每个特征点都对应3D点重投影误差即可得到位姿
                    bOK = TrackReferenceKeyFrame();//跟踪参考帧
                }
                else
                {
                    // 根据恒速模型设定当前帧的初始位姿
                    // 通过投影的方式在参考帧中找当前帧特征点的匹配点
                    // 优化每个特征点所对应3D点的投影误差即可得到位姿
                    bOK = TrackWithMotionModel();//根据固定运动速度模型预测当前帧的位姿
                    if(!bOK)
                        // TrackReferenceKeyFrame是跟踪参考帧,不能根据固定运动速度模型预测当前帧的位姿态,通过bow加速匹配(SearchByBow)
                        // 最后通过优化得到优化后的位姿
                        bOK = TrackReferenceKeyFrame();
                }
            }
            else
            {
                // BOW搜索,PnP求解位姿
                bOK = Relocalization()//重定位成功与否
            }
        }
        else
        {
            // Localization Mode: Local Mapping is deactivated
            // 只进行跟踪tracking,局部地图不工作
            // 步骤2.1:跟踪上一帧或者参考帧或者重定位
            // tracking跟丢了
            if(mState==LOST)
            {                
              bOK = Relocalization();//判断重定位成功与否标志
            }
           else
            {
               // mbVO是mbOnlyTracking为true时的才有的一个变量
                // mbVO为false表示此帧匹配了很多的MapPoints,跟踪很正常,
                // mbVO为true表明此帧匹配了很少的MapPoints,少于10个,要跪的节奏
               if(!mbVO)
                {
                   // In last frame we tracked enough MapPoints in the map
                    // mbVO为0则表明此帧匹配了很多的3D map点,非常好
                    if(!mVelocity.empty())
                    {
                       bOK = TrackWithMotionModel();
                                            }
                    else
                    {
                        bOK = TrackReferenceKeyFrame();
                    }
                }
                else
                {
                    // In last frame we tracked mainly "visual odometry" points.在上一帧我们主要跟踪视觉里程计点
                    // We compute two camera poses, one from motion model and one doing relocalization.我们由运动模型和重定位计算相机位姿
                    // If relocalization is sucessfull we choose that solution, otherwise we retain
                    // the "visual odometry" solution.
                    // mbVO为1,则表明此帧匹配了很少的3D map点,少于10个,要跪的节奏,既做跟踪又做定位
                    bool bOKMM = false;//运动模型是否成功判断标志
                    bool bOKReloc = false;//重定位是否成功判断标志
                    vector<MapPoint*> vpMPsMM;//记录地图点
                    vector<bool> vbOutMM;//记录外点
                    cv::Mat TcwMM;//变换矩阵
                    if(!mVelocity.empty())//有速度
                    {
                        bOKMM = TrackWithMotionModel();//用运动模型追踪
                        vpMPsMM = mCurrentFrame.mvpMapPoints;//记录地图点
                        vbOutMM = mCurrentFrame.mvbOutlier;//记录外点
                        TcwMM = mCurrentFrame.mTcw.clone();//当前帧的变换矩阵
                    }
                    bOKReloc = Relocalization();//用重定位
                    // 重定位没有成功,但是运动模型跟踪成功
                    if(bOKMM && !bOKReloc)
                    {
                        mCurrentFrame.SetPose(TcwMM);
                        mCurrentFrame.mvpMapPoints = vpMPsMM;
                        mCurrentFrame.mvbOutlier = vbOutMM;
                        if(mbVO)
                        {
                            // 更新当前帧的MapPoints被观测程度
                            for(int i =0; i<mCurrentFrame.N; i++)
                            {
                                if(mCurrentFrame.mvpMapPoints[i] && !mCurrentFrame.mvbOutlier[i])
                                {
                                    mCurrentFrame.mvpMapPoints[i]->IncreaseFound();
                                }
 
                            }
                        }
                    }
                    else if(bOKReloc)// 只要重定位成功整个跟踪过程正常进行(定位与跟踪,更相信重定位)
                    {
                        mbVO = false;
                    }
                    bOK = bOKReloc || bOKMM;
               }
            }
        }

2.3.2. local map跟踪

在帧间匹配得到初始的姿态后,现在对local map进行跟踪得到更多的匹配,并优化当前位姿,local map:当前帧、当前帧的MapPoints、当前关键帧与其它关键帧共视关系,在上一步中主要是两两跟踪(恒速模型跟踪上一帧、跟踪参考帧),这里搜索局部关键帧后搜集所有局部MapPoints,然后将局部MapPoints和当前帧进行投影匹配,得到更多匹配的MapPoints后进行Pose优化。

2.4. 速度模型

更新恒速运动模型TrackWithMotionModel中的mVelocity

  // 将最新的关键帧作为reference frame,接上面代码
        mCurrentFrame.mpReferenceKF = mpReferenceKF;
 if(!mbOnlyTracking)
        {
            if(bOK)
                bOK = TrackLocalMap();
        }
        else
        {
           // mbVO true means that there are few matches to MapPoints in the map. We cannot retrieve
            // a local map and therefore we do not perform TrackLocalMap(). Once the system relocalizes
            // the camera we will use the local map again.
            // 重定位成功
            if(bOK && !mbVO)
                bOK = TrackLocalMap();
        }
        if(bOK)
            mState = OK;
        else
            mState=LOST;
        // Update drawer
        mpFrameDrawer->Update(this);
        // If tracking were good, check if we insert a keyframe
        if(bOK)
        {
            // Update motion model
            if(!mLastFrame.mTcw.empty())
            {
                // 步骤2.3:更新恒速运动模型TrackWithMotionModel中的mVelocity
                cv::Mat LastTwc = cv::Mat::eye(4,4,CV_32F);
                mLastFrame.GetRotationInverse().copyTo(LastTwc.rowRange(0,3).colRange(0,3));
              mLastFrame.GetCameraCenter().copyTo(LastTwc.rowRange(0,3).col(3));
               mVelocity = mCurrentFrame.mTcw*LastTwc; // 其实就是Tcl
            } 
            else
                mVelocity = cv::Mat();
            mpMapDrawer->SetCurrentCameraPose(mCurrentFrame.mTcw);
 

2.4.1. 清除UpdateLastFrame中为当前帧临时添加的MapPoints

清除临时的MapPoints,这些MapPoints在TrackWithMotionModel的UpdateLastFrame函数里生成(仅双目和rgbd)

检测并插入关键帧,对于双目会产生新的MapPoints

 // 步骤2.4:清除UpdateLastFrame中为当前帧临时添加的MapPoints
            for(int i=0; i<mCurrentFrame.N; i++)//遍历当前帧所有MapPoint
            {
                MapPoint* pMP = mCurrentFrame.mvpMapPoints[i];
                if(pMP)
                    // 排除UpdateLastFrame函数中为了跟踪增加的MapPoints
                    if(pMP->Observations()<1)
                    {
                        mCurrentFrame.mvbOutlier[i] = false;
                        mCurrentFrame.mvpMapPoints[i]=static_cast<MapPoint*>(NULL);
                    }
            }
 
            // Delete temporal MapPoints
            // 步骤2.5:清除临时的MapPoints,这些MapPoints在TrackWithMotionModel的UpdateLastFrame函数里生成(仅双目和rgbd)
            // 步骤2.4中只是在当前帧中将这些MapPoints剔除,这里从MapPoints数据库中删除
            // 这里生成的仅仅是为了提高双目或rgbd摄像头的帧间跟踪效果,用完以后就扔了,没有添加到地图中
            for(list<MapPoint*>::iterator lit = mlpTemporalPoints.begin(), lend =  mlpTemporalPoints.end(); lit!=lend; lit++)
            {
                MapPoint* pMP = *lit;
                delete pMP;
            }
            // 这里不仅仅是清除mlpTemporalPoints,通过delete pMP还删除了指针指向的MapPoint
            mlpTemporalPoints.clear();
            // Check if we need to insert a new keyframe
           // 步骤2.6:检测并插入关键帧,对于双目会产生新的MapPoints
            if(NeedNewKeyFrame())
                CreateNewKeyFrame();
            // We allow points with high innovation (considererd outliers by the Huber Function)我们允许具有高创新点(考虑胡贝尔函数的异常值)
            // pass to the new keyframe, so that bundle adjustment will finally decide传递到新的关键帧,这样束调整将最终决定
            // if they are outliers or not. We don't want next frame to estimate its position如果它们是外点。我们不希望下一帧估计它的位置。
            // with those points so we discard them in the frame.
            // 删除那些在bundle adjustment中检测为outlier的3D map点
            for(int i=0; i<mCurrentFrame.N;i++)
            {
                if(mCurrentFrame.mvpMapPoints[i] && mCurrentFrame.mvbOutlier[i])
                   mCurrentFrame.mvpMapPoints[i]=static_cast<MapPoint*>(NULL);
            }
        }
        // Reset if the camera get lost soon after initialization
        // 跟踪失败,并且relocation也没有搞定,只能重新Reset
        if(mState==LOST)
        {
            if(mpMap->KeyFramesInMap()<=5)
            {
                cout << "Track lost soon after initialisation, reseting..." << endl;
                mpSystem->Reset();
                return;
            }
        }
        if(!mCurrentFrame.mpReferenceKF)
            mCurrentFrame.mpReferenceKF = mpReferenceKF;
        // 保存上一帧的数据
        mLastFrame = Frame(mCurrentFrame);
    }

2.5. 记录位姿信息,用于轨迹复现

if(!mCurrentFrame.mTcw.empty())
    {
        // 计算相对姿态T_currentFrame_referenceKeyFrame
        cv::Mat Tcr = mCurrentFrame.mTcw*mCurrentFrame.mpReferenceKF->GetPoseInverse();
        mlRelativeFramePoses.push_back(Tcr);
        mlpReferences.push_back(mpReferenceKF);
        mlFrameTimes.push_back(mCurrentFrame.mTimeStamp);
        mlbLost.push_back(mState==LOST);
    }
    else
    {
        // This can happen if tracking is lost
        // 如果跟踪失败,则相对位姿使用上一次值
        mlRelativeFramePoses.push_back(mlRelativeFramePoses.back());
        mlpReferences.push_back(mlpReferences.back());
        mlFrameTimes.push_back(mlFrameTimes.back());
        mlbLost.push_back(mState==LOST);
    }
}

参考文献

主要内容来自下文,注释略有增改

ORB-SLAM2从理论到代码实现(六):Tracking.cc程序详解(上)_track lost soon after initialisation, reseting...-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/635297.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

wordpress主题 ACG美化插件v3.4.2支持zibll主题7b2主题美化

独具一格的二次元风格&#xff0c;打造全新的子比美化方向 大部分代码均为CSS、JS做成插件只是为了方便懒人小白站长 后台全功能一览&#xff0c;大部分美化均为网上通用流传&#xff0c;

基于ucos-ii操作系统的生产者消费者-问题

目 录 第1章 题目分析. 1 1.1 生产者线程... 1 1.2 消费者线程... 1 1.3 缓冲区... 1 1.4 进程的同步与互斥... 1 第2章 解决方案. 2 2.1 总体方案... 2 2.2 生产者问题... 2 2.3 消费者问题... 3 2.4 进程问题... 5 第3章 实验结果. 6 3.1 运行结果... 6 3.2 结果分析... 8 第…

用kimi一键绘制《庆余年》人物关系图谱

《庆余年》里面人物关系复杂&#xff0c;如果能画出一个人物关系图谱&#xff0c;可以直观的理解其中人物关系&#xff0c;更好的追剧。 首先&#xff0c;用kimi下载庆余年的分集剧情&#xff0c;常见文章《AI网络爬虫&#xff1a;批量爬取电视猫上面的《庆余年》分集剧情》&am…

【Java面试】三、Redis篇(下)

文章目录 1、抢券场景2、Redis分布式锁3、Redisson实现分布式锁4、Redisson实现的分布式锁是可重入锁5、Redisson实现分布式锁下的主从一致性6、面试 1、抢券场景 正常思路&#xff1a; 代码实现&#xff1a; 比如优惠券数量为1。正常情况下&#xff1a;用户A的请求过来&a…

Centos7.9上安装Oracle 11gR2 RAC 三节点(ASMlib管理asm磁盘)

服务器规划 OS 规格 主机名 IP VIP private IP scanip centos 7.9 1C4G racdb01 192.168.40.165 192.168.183.165 192.168.40.16 192.168.40.200 centos 7.9 1C4G racdb02 192.168.40.175 192.168.183.175 192.168.40.17 192.168.40.200 centos 7.9 1C4G…

目前流行的前端框架有哪些?

目前流行的前端框架有很多&#xff0c;它们可以帮助开发者快速构建高质量的前端应用程序。本文将介绍一些目前比较受欢迎的前端框架&#xff0c;并分析它们的优缺点。 React React 是一个由 Facebook 开发的开源前端JavaScript库&#xff0c;用于构建用户界面&#xff0c;尤其…

基于Vue的图片文件上传与压缩组件的设计与实现

摘要 随着前端技术的发展&#xff0c;系统开发的复杂度不断提升&#xff0c;传统开发方式将整个系统做成整块应用&#xff0c;导致修改和维护成本高昂。组件化开发作为一种解决方案&#xff0c;能够实现单独开发、单独维护&#xff0c;并能灵活组合组件&#xff0c;从而提升开…

OSPF多区域组网实验(华为)

思科设备参考&#xff1a;OSPF多区域组网实验&#xff08;思科&#xff09; 技术简介 OSPF多区域功能通过划分网络为多个逻辑区域来提高网络的可扩展性和管理性能。每个区域内部运行独立的SPF计算&#xff0c;而区域之间通过区域边界路由器进行路由信息交换。这种划分策略适用…

Python 机器学习 基础 之 数据表示与特征工程 【分类变量】的简单说明

Python 机器学习 基础 之 数据表示与特征工程 【分类变量】的简单说明 目录 Python 机器学习 基础 之 数据表示与特征工程 【分类变量】的简单说明 一、简单介绍 二、数据表示与特征工程 数据表示 特征工程 三、分类变量 1、One-Hot编码&#xff08;虚拟变量&#xff09…

【ArcGIS微课1000例】0112:沿线(面)按距离或百分比生成点

文章目录 一、沿线生成点工具介绍二、线状案例三、面状案例一、沿线生成点工具介绍 位置:工具箱→数据管理工具→采样→沿线生成点 摘要:沿线或面以固定间隔或百分比创建点要素。 用法:输入要素的属性将保留在输出要素类中。向输出要素类添加新字段 ORIG_FID,并设置为输…

Vue进阶之Vue项目实战(三)

Vue项目实战 图表渲染安装echarts图表渲染器(图表组件)图表举例:创建 ChartsRenderer.vue创建 ChartsDataTransformer.ts基于 zrender 开发可视化物料安装 zrender画一个矩形画一个柱状图基于svg开发可视化物料svg小示例使用d3进行图表渲染安装d3基本使用地图绘制本地持久化拓…

Leetcode861. 翻转矩阵后的得分

Every day a Leetcode 题目来源&#xff1a;861. 翻转矩阵后的得分 解法1&#xff1a;贪心 对于二进制数来说&#xff0c;我们只要保证最高位是1&#xff0c;就可以保证这个数是最大的&#xff0c;因为移动操作会使得它取反&#xff0c;因此我们进行行变化的时候只需要考虑首…

深度学习:手撕 RNN(2)-RNN 的常见模型架构

本文首次发表于知乎&#xff0c;欢迎关注作者。 上一篇文章我们介绍了一个基本的 RNN 模块。有了 这个 RNN 模块后&#xff0c;就像搭积木一样&#xff0c;以 RNN 为基本单元&#xff0c;根据不同的任务或者需求&#xff0c;可以构建不同的模型架构。本节介绍的所有结构&#…

Glassnode 内容主管:「减半」后的市场「抑郁」

原文标题&#xff1a;《Finance Bridge: Post-Halving Blues》撰文&#xff1a;Marcin Miłosierny&#xff0c;Glassnode 内容主管编译&#xff1a;Chris&#xff0c;Techub News 文章来源香港Web3媒体Techun News 摘要&#xff1a; 每月简报&#xff1a;4 月&#xff0c;尽…

前端自动将 HTTP 请求升级为 HTTPS 请求

前端将HTTP请求升级为HTTPS请求有两种方式&#xff1a; 一、index.html 中插入meta 直接在首页 index.html 的 head 中加入一条 meta 即可&#xff0c;如下所示&#xff1a; <meta http-equiv"Content-Security-Policy" content"upgrade-insecure-requests&…

从零开始傅里叶变换

从零开始傅里叶变换 1 Overview2 傅里叶级数2.1 基向量2.2 三角函数系表示 f ( t ) f(t) f(t)2.2.1 三角函数系的正交性2.2.2 三角函数系的系数 2.3 复指数函数系表示 f ( t ) f(t) f(t)2.3.1 复指数函数系的系数2.3.2 复指数函数系的正交性 2.4 傅里叶级数总结 3 傅里叶变换…

C++BuilderXE 如何让listView按文件名数字排序而非字母排序

int m_nDataColSort0; bool IsAsctrue; void __fastcall TForm1::RzListView4Compare(TObject *Sender, TListItem *Item1, TListItem *Item2, int Data, int &Compare) { if(m_nDataColSort0) { //按列表第二列排序 //CompareCompareText(Item1->SubItems-…

FreeRTOS学习——FreeRTOS队列(下)之队列创建

本篇文章记录我学习FreeRTOS队列创建的知识。主要分享队列创建需要使用的初始化函数、队列复位函数。 需要进一步了解FreeRTOS队列的相关知识&#xff0c;读者可以参考以下文章&#xff1a; FreeRTOS学习——FreeRTOS队列&#xff08;上&#xff09;_freertos 单元素队列-CSDN博…

第四节 Starter 加载时机和源码理解

tips&#xff1a;每个 springBoot 的版本不同&#xff0c;代码的实现存会存在不同。 上一章&#xff0c;我们聊到 mybatis-spring-boot-starter&#xff1b; 简单分析了它的结构。 这一章我们将着重分析 Starter 的加载机制&#xff0c;并结合源码进行分析理解。 一、加载实际…

基于魏格纳函数和焦散线方法的自加速光束matlab模拟与仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于魏格纳函数和焦散线方法的自加速光束matlab模拟与仿真。通过魏格纳函数法&#xff0c;来产生多种自加速的光束&#xff0c;设计自加速光束方法&#xff0c;模…