完整指南:CNStream流处理多路并发框架适配到NVIDIA Jetson Orin (四) 运行、调试、各种问题解决

目录

1 调试jetson-mpeg视频解码模块

1.1 修改config.json

1.2 Picture size 0x0 is invalid

1.3 Process(): Send package failed. Maximum number of attempts reached

1.4 Picture size 2239821608x65535 is invalid

1.5 保存h264文件解码之后的测试图片

1.6 保存RTSP视频解码之后的测试图片

2 调试cv-cuda图片处理模块

2.1 NVCV_ERROR_NOT_IMPLEMENTED: Batch image format must not have subsampled planes, 

2.2 保存NVConvertFormat之后的图片

 参考文献:


记录下将CNStream流处理多路并发Pipeline框架适配到NVIDIA Jetson AGX Orin的过程,以及过程中遇到的问题,我的jetson盒子是用jetpack5.1.3重新刷机之后的,这是系列博客的第四篇,前三篇链接如下:

完整指南:CNStream流处理多路并发框架适配到NVIDIA Jetson Orin (一) 依赖库编译、第三方库编译安装-CSDN博客

完整指南:CNStream流处理多路并发框架适配到NVIDIA Jetson Orin (二) 源码架构流程梳理、代码编写-CSDN博客

完整指南:CNStream流处理多路并发框架适配到NVIDIA Jetson Orin (三) 代码编译、各种问题解决、代码修改-CSDN博客

这篇博客记录下程序运行过程中遇到的错误、以及调试解决各种错误的过程。

1 调试jetson-mpeg视频解码模块

1.1 修改config.json

先把config.json修改成最简单的方式,只保留解码模块

{
  "profiler_config" : {
    "enable_profiling" : false,
    "enable_tracing" : false
  },

  "subgraph:decode" : {
    "config_path" : "configs/decode_config.json"
  },
  
  "subgraph:business" : {
    "config_path" : "configs/business.json"
  }
  
  

}

然后开始运行、调试,

1.2 Picture size 0x0 is invalid

I0909 17:30:40.658268 943351 data_handler_file.cpp:304] [TACLStream SOURCE INFO] [FileHandlerImpl] OnParserInfo(): [5g3223522224262]: Got video info.
I0909 17:30:40.658645 943351 decode_impl_nv.cpp:45] [InferServer] [DecodeFFmpeg] Create(): Use codec type: h264_nvmpi
[h264_nvmpi @ 0xffff100035f0] [IMGUTILS @ 0xffff34fc4770] Picture size 0x0 is invalid
[h264_nvmpi @ 0xffff100035f0] video_get_buffer: image parameters invalid
[h264_nvmpi @ 0xffff100035f0] get_buffer() failed
[h264_nvmpi @ 0xffff100035f0] [IMGUTILS @ 0xffff34fc4770] Picture size 0x0 is invalid
[h264_nvmpi @ 0xffff100035f0] video_get_buffer: image parameters invalid
[h264_nvmpi @ 0xffff100035f0] get_buffer() failed
E0909 17:30:40.659263 943351 decode_impl_nv.cpp:67] [InferServer] [DecodeFFmpeg] Failed to open codec
E0909 17:30:40.660058 943351 decode.cpp:64] [InferServer] [DecodeService] Create(): Create decoder failed
E0909 17:30:40.660167 943351 video_decoder.cpp:88] [TACLStream SOURCE ERROR] [5g3223522224262]: Create decoder failed
E0909 17:30:40.660254 943351 data_handler_file.cpp:315] [TACLStream SOURCE ERROR] [FileHandlerImpl] OnParserInfo(): Create decoder failed, ret = 0
E0909 17:30:40.660997 943351 data_handler_file.cpp:220] [TACLStream SOURCE ERROR] [FileHandlerImpl] Loop(): [5g3223522224262]: PrepareResources failed.
W0909 17:30:40.661371 941831 task_session_mgr.cpp:855] [TACLStream SESSION_MGR WARN] [TNVPipeline] received stream error from stream: 5g3223522224262, remove it from pipeline.

在ffmpeg的源码中搜了下这个报错,

看了下代码,应该是宽高没设置的问题,但是我找了半天这个ff_get_buffer是怎么被avcodec_open2函数调用的,没找到,于是我直接吧nvmpi和ffmepg这两个库都编译成debug版本然后调试。

首先把jetson-ffmpeg编译成debug版本,修改其中的cmake那一行

git clone https://github.com/Keylost/jetson-ffmpeg.git
cd jetson-ffmpeg
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Debug ..
make
sudo make install
sudo ldconfig

然后把ffmpeg编译一个debug版本,修改其中的config那一行

./configure --enable-static --enable-shared --enable-nvmpi --enable-debug=3 --disable-optimizations
git clone git://source.ffmpeg.org/ffmpeg.git -b release/4.4 --depth=1
cd ffmpeg
cp /data/chw/jetson-ffmpeg/ffmpeg_patches/ffmpeg4.4_nvmpi.patch /data/chw/ffmpeg/ffmpeg_nvmpi.patch
git apply ffmpeg_nvmpi.patch
./configure --enable-static --enable-shared --enable-nvmpi
make -j8
make install
ldconfig

然后调试看,找到了调用关系

然后报错是因为这里的宽高没给他赋值,判断是0就会报错。

另外,在查找这个bug的过程中发现,ffmpeg里面还有个问题就是数据格式如果传NV12那么里面也会报错提示不支持,所以这里还需要修改ffmpeg内部的源码,重新编译库,

另外,我的解码代码加上这几行

        codec_context_->pix_fmt = AV_PIX_FMT_NV12;
        codec_context_->width = create_params_.max_width;
        codec_context_->height = create_params_.max_height;

1.3 Process(): Send package failed. Maximum number of attempts reached

这个错误我检查了代码也没发现错误呀,调试也没调试出来啥,然后我看了下我的视频文件是用的一个mp4文件,我换成一个.h264视频文件就没有这个错误了。

1.4 Picture size 2239821608x65535 is invalid

[h264_nvmpi @ 0xffff00000e30] [IMGUTILS @ 0xffff26affa60] Picture size 2239821608x65535 is invalid
[h264_nvmpi @ 0xffff00000e30] [IMGUTILS @ 0xffff26affa10] Picture size 0x0 is invalid
[h264_nvmpi @ 0xffff00000e30] video_get_buffer: image parameters invalid
[h264_nvmpi @ 0xffff00000e30] get_buffer() failed
E0910 17:38:43.887912 1224545 decode_impl_nv.cpp:70] [InferServer] [DecodeFFmpeg] Failed to open codec
E0910 17:38:43.890803 1224545 decode.cpp:64] [InferServer] [DecodeService] Create(): Create decoder failed
E0910 17:38:43.891697 1224545 video_decoder.cpp:88] [TACLStream SOURCE ERROR] [5g3223522224262]: Create decoder failed
E0910 17:38:43.891896 1224545 data_handler_rtsp.cpp:515] [TACLStream SOURCE ERROR] [RtspHandlerImpl] DecodeLoop(): Create decoder failed.

我把mp4文件换成RTSP,报错

我调试进去看了下是因为宽高没被赋值。然后我调试到处理RTSP流的地方,发现

其实这里是有获取这两个值的代码的,并且我调试看到也有值,只不过这两行代码之前被注释掉了,放开注释。

然后重新编译、运行,刚才的报错消失。

1.5 保存h264文件解码之后的测试图片

在这里增加测试代码,直接用opencv保存图片

    void DecodeFFmpeg::OnFrame(AVFrame *av_frame, uint32_t frame_id) {

        static int debug_count  = 0;
        cv::Mat yuv_mat(av_frame_->height * 3 / 2, av_frame_->width, CV_8UC1, av_frame_->data[0]);//调试代码,记得修改。
        cv::Mat bgr_mat;
        cv::cvtColor(yuv_mat, bgr_mat, cv::COLOR_YUV2BGR_NV12); //调试代码,记得修改,这是原代码  
        debug_count =  debug_count + 1;
        char decode_name[20] = {};

        if((debug_count < 3000) && (debug_count % 2 == 0))
        {
            sprintf(decode_name, "OnDecodeFrame_%d.jpg",  debug_count);
            cv::imwrite(decode_name, bgr_mat);
        }

        BufSurface *surf{};
        if (create_params_.GetBufSurf(&surf, av_frame_->width, av_frame->height, BUF_COLOR_FORMAT_BGR,
            create_params_.surf_timeout_ms, create_params_.userdata) < 0) {
            LOG(ERROR) << "[InferServer] [DecoderAcl] OnFrame(): Get BufSurface failed";
            OnError(-1);
            return;}
        if (surf->mem_type != BUF_MEMORY_MANAGED) {
            LOG(ERROR) << "[InferServer] [DecoderAcl] OnFrame(): BufSurface memory type must be BUF_MEMORY_MANAGED";
            return;
        }

发现图片保存不正常,

好吧,

我写代码直接保存yuv文件

    void DecodeFFmpeg::SaveYUVFrame(AVFrame *av_frame, const char *filename) {
        FILE *file = fopen(filename, "wb");
        if (!file) {
            fprintf(stderr, "Could not open %s for writing\n", filename);
            return;
        }

        // 写入 Y 分量
        for (int i = 0; i < av_frame->height; i++) {
            fwrite(av_frame->data[0] + i * av_frame->linesize[0], 1, av_frame->width, file);
        }

        // 写入交错的 UV 分量
        for (int i = 0; i < av_frame->height / 2; i++) {
            fwrite(av_frame->data[1] + i * av_frame->linesize[1], 1, av_frame->width, file);
        }

        // // 写入 U 分量
        // for (int i = 0; i < av_frame->height / 2; i++) {
        //     fwrite(av_frame->data[1] + i * av_frame->linesize[1], 1, av_frame->width / 2, file);
        // }

        // // 写入 V 分量
        // for (int i = 0; i < av_frame->height / 2; i++) {
        //     fwrite(av_frame->data[1] + (av_frame->height / 2)*av_frame->linesize[1] + i * av_frame->linesize[1], 1, av_frame->width / 2, file);
        // }

        fclose(file);
    }

然后

    void DecodeFFmpeg::OnFrame(AVFrame *av_frame, uint32_t frame_id) {

        static int debug_count  = 0;
        cv::Mat yuv_mat(av_frame_->height * 3 / 2, av_frame_->width, CV_8UC1, av_frame_->data[0]);//调试代码,记得修改。
        cv::Mat bgr_mat;
        cv::cvtColor(yuv_mat, bgr_mat, cv::COLOR_YUV2BGR_NV12); //调试代码,记得修改,这是原代码  
        debug_count =  debug_count + 1;
        char decode_name[20] = {};


        // 保存 YUV 数据
        if (debug_count < 3000 && debug_count % 2 == 0) {
            char yuv_filename[20];
            sprintf(yuv_filename, "frame_%d.yuv", debug_count);
            SaveYUVFrame(av_frame, yuv_filename);
        }

        if((debug_count < 3000) && (debug_count % 2 == 0))
        {
            
            sprintf(decode_name, "OnDecodeFrame_%d.jpg",  debug_count);
            cv::imwrite(decode_name, bgr_mat);
        }

yuv文件打开正常。 

那么就是我的yuv转BGR的代码有问题了,

我把代码改成下面这种

    void DecodeFFmpeg::OnFrame(AVFrame *av_frame, uint32_t frame_id) {

        static int debug_count  = 0;
        //cv::Mat yuv_mat(av_frame_->height * 3 / 2, av_frame_->width, CV_8UC1, av_frame_->data[0]);//调试代码,记得修改。
        cv::Mat yuv_mat(av_frame_->height * 3 / 2, av_frame_->width, CV_8UC1);//调试代码,记得修改。
        // 拷贝 Y 分量数据
        memcpy(yuv_mat.data, av_frame->data[0], av_frame->height * av_frame->linesize[0]);

        // 拷贝 UV 分量数据
        memcpy(yuv_mat.data + av_frame->height * av_frame->linesize[0], av_frame->data[1], av_frame->height / 2 * av_frame->linesize[1]);
        cv::Mat bgr_mat;
        cv::cvtColor(yuv_mat, bgr_mat, cv::COLOR_YUV2BGR_NV12); //调试代码,记得修改,这是原代码  
        debug_count =  debug_count + 1;
        char decode_name[20] = {};


        // 保存 YUV 数据
        if (debug_count < 3000 && debug_count % 2 == 0) {
            char yuv_filename[20];
            sprintf(yuv_filename, "frame_%d.yuv", debug_count);
            SaveYUVFrame(av_frame, yuv_filename);
        }

        if((debug_count < 3000) && (debug_count % 2 == 0))
        {
            
            sprintf(decode_name, "OnDecodeFrame_%d.jpg",  debug_count);
            cv::imwrite(decode_name, bgr_mat);
        }

跟之前的区别在与我先创建一个mat,然后我memcpy分别从data[0]和data[1]拷贝两次,这样保存的图片正常,那么问题出在哪里。我觉得在于av_frame_->data[0]是Y分量,av_frame_->data[1]是UV分量,但是av_frame_->data[0]和av_frame_->data[1]之间并不是连续的,我用计算器验证一下,这个是av_frame_->data[0]和av_frame_->data[1]的差。

这个是1920*1080的值。 

1.6 保存RTSP视频解码之后的测试图片

 解码RTSP视频流,保存图片正常。

2 调试cv-cuda图片处理模块

2.1 NVCV_ERROR_NOT_IMPLEMENTED: Batch image format must not have subsampled planes, 

运行报错

terminate called after throwing an instance of 'nvcv::Exception'
  what():  NVCV_ERROR_NOT_IMPLEMENTED: Batch image format must not have subsampled planes, but it is: NVCV_IMAGE_FORMAT_NV12
Aborted (core dumped)

直接问下必应

修改代码,将

nvcv::Tensor::Requirements in_reqs = nvcv::Tensor::CalcRequirements(1, { buf_surf.width_stride, buf_surf.height }, CastColorFmt(buf_surf.color_format));

修改成下面的代码,也就是按照FMT_U8给yuv申请tensor。

        if (buf_surf.color_format == BUF_COLOR_FORMAT_NV12 || buf_surf.color_format == BUF_COLOR_FORMAT_NV21) {
            in_reqs = nvcv::Tensor::CalcRequirements(1, { buf_surf.width, buf_surf.height * 3 / 2 }, nvcv::FMT_U8);
        }
        else {
            in_reqs = nvcv::Tensor::CalcRequirements(1, { buf_surf.width, buf_surf.height }, CastColorFmt(buf_surf.color_format));
        }

2.2 保存NVConvertFormat之后的图片

我在这个函数最后面增加测试代码,保存测试图片


    int TransformerNV::NVConvertFormat(BufSurface *src, BufSurface *dst, TransformParams *transform_params) {
        auto& src_surf = src->surface_list[0];
        auto& dst_surf = dst->surface_list[0];

        auto src_tensor = GetTensorFromBufSurf(src_surf);
        auto dst_tensor = GetTensorFromBufSurf(dst_surf);

        NVCVColorConversionCode cvt_code{ NVCV_COLOR_YUV2BGR_NV12 };
        switch (src_surf.color_format) {
        case BUF_COLOR_FORMAT_NV12:
        {
            if (dst_surf.color_format == BUF_COLOR_FORMAT_BGR) {
                cvt_code = NVCV_COLOR_YUV2BGR_NV12;
            }
        }break;
        case BUF_COLOR_FORMAT_BGR:
        {
            if (dst_surf.color_format == BUF_COLOR_FORMAT_NV12) {
                cvt_code = NVCV_COLOR_BGR2YUV_NV12;
            }
        }break;
        case BUF_COLOR_FORMAT_RGB:
        {
            if (dst_surf.color_format == BUF_COLOR_FORMAT_NV12) {
                cvt_code = NVCV_COLOR_RGB2YUV_NV12;
            }
        }break;
        default:
            cvt_code = NVCV_COLOR_YUV2BGR_NV12;
        }

        if ((src_surf.color_format == BUF_COLOR_FORMAT_NV12 || src_surf.color_format == BUF_COLOR_FORMAT_NV21)
            && (dst_surf.color_format == BUF_COLOR_FORMAT_BGR || dst_surf.color_format == BUF_COLOR_FORMAT_RGB)) {
            cvt_code = NVCV_COLOR_YUV2BGR_NV12;
        }
        else if ((src_surf.color_format == BUF_COLOR_FORMAT_NV12 || src_surf.color_format == BUF_COLOR_FORMAT_NV21)
                 && (dst_surf.color_format == BUF_COLOR_FORMAT_BGR || dst_surf.color_format == BUF_COLOR_FORMAT_RGB)) {
            cvt_code = NVCV_COLOR_YUV2BGR_NV12;
        }

        (*cvtcolor_op_)(reinterpret_cast<cudaStream_t>(cu_stream_), src_tensor, dst_tensor, cvt_code);
        CUDA_SAFECALL(cuStreamSynchronize(cu_stream_)
                      , "[InferServer] [TransformerNV] NVConvertFormat failed.", -1);
 
        // Assuming 'dst_tensor' holds the converted BGR data.
        cv::Mat bgr_image(dst_surf.height, dst_surf.width, CV_8UC3, dst->surface_list[0].data_ptr);
        cv::imwrite("output_image.jpg", bgr_image);


        return 0;
    }

结果如下,

我知道是什么原因,这是因为前面解码的时候,解码结束之后赋值内存的时候用的是av_frame_->data,问题原因就和上面保存解码测试图片一样的。

 参考文献:

在NVIDIA Jetson AGX Orin中使用jetson-ffmpeg调用硬件编解码加速处理-CSDN博客

NVIDIA Jetson AGX Orin源码编译安装CV-CUDA-CSDN博客

GitHub - Cambricon/CNStream: CNStream is a streaming framework for building Cambricon machine learning pipelines http://forum.cambricon.com https://gitee.com/SolutionSDK/CNStream

easydk/samples/simple_demo/common/video_decoder.cpp at master · Cambricon/easydk · GitHub

aclStream流处理多路并发Pipeline框架中 视频解码 代码调用流程整理、类的层次关系整理、回调函数赋值和调用流程整理-CSDN博客

aclStream流处理多路并发Pipeline框架中VEncode Module代码调用流程整理、类的层次关系整理、回调函数赋值和调用流程整理-CSDN博客

FFmpeg/doc/examples at master · FFmpeg/FFmpeg · GitHub

GitHub - CVCUDA/CV-CUDA: CV-CUDA™ is an open-source, GPU accelerated library for cloud-scale image processing and computer vision.

如何使用FFmpeg的解码器—FFmpeg API教程 · FFmpeg原理

C++ API — CV-CUDA Beta documentation (cvcuda.github.io)

CV-CUDA/tests/cvcuda/system at main · CVCUDA/CV-CUDA · GitHub

Resize — CV-CUDA Beta documentation

CUDA Runtime API :: CUDA Toolkit Documentation

CUDA Toolkit Documentation 12.6 Update 1

完整指南:CNStream流处理多路并发框架适配到NVIDIA Jetson Orin (一) 依赖库编译、第三方库编译安装-CSDN博客

完整指南:CNStream流处理多路并发框架适配到NVIDIA Jetson Orin (二) 源码架构流程梳理、代码编写-CSDN博客

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

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

相关文章

【CanMV K230 AI视觉】 人体检测

【CanMV K230 AI视觉】 人体检测 人体检测 动态测试效果可以去下面网站自己看。 B站视频链接&#xff1a;已做成合集 抖音链接&#xff1a;已做成合集 人体检测 人体检测是判断摄像头画面中有无出现人体&#xff0c;常用于人体数量检测&#xff0c;人流量监控以及安防监控等。…

“版权护航·星影计划”暨电影《末代天师》发布仪式

2024 年 9 月 10 日&#xff0c;由华纳星辰&#xff08;北京&#xff09;文化传媒有限公司与浙江焱煌影视文化传媒有限公司共同主办的 “版权护航・星影计划” 暨网络电影《末代天师》新闻发布会&#xff0c;在北京渔阳饭店世纪宴会厅华彩盛启。 北京影视艺术学会会长张连生、中…

springboot luttuc redis 集成protobuf,手动序列化反序列化

前置需知&#xff1a; 1.本文章和网上大部分博客配置不太一样&#xff0c;各位看官要分析一下自己的需求。集成protobuf 本文章主要是手动调用protobuf的序列化方法&#xff0c;而不是交由springboot 去做&#xff0c;会偏向原生java 使用方式 2.由于为了和公司其他的项目达成…

每日OJ_牛客_合唱团(打家劫舍dp)

目录 牛客_合唱团&#xff08;打家劫舍dp&#xff09; 解析代码1 解析代码2 牛客_合唱团&#xff08;打家劫舍dp&#xff09; 合唱团__牛客网 有 n 个学生站成一排&#xff0c;每个学生有一个能力值&#xff0c;牛牛想从这 n 个学生中按照顺序选取 k 名学生&#xff0c;要求…

【Linux】文件权限与类型全解:你的文件安全指南

欢迎来到 CILMY23 的博客 &#x1f3c6;本篇主题为&#xff1a;文件权限与类型全解&#xff1a;你的文件安全指南 &#x1f3c6;个人主页&#xff1a;CILMY23-CSDN博客 &#x1f3c6;系列专栏&#xff1a;Python | C | C语言 | 数据结构与算法 | 贪心算法 | Linux | 算法专题…

EmguCV学习笔记 VB.Net 11.5 目标检测

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的。 EmguCV是一个基于OpenCV的开源免费的跨平台计算机视觉库,它向C#和VB.NET开发者提供了OpenCV库的大部分功能。 教程VB.net版本请访问…

Day7 | Java框架 | SpringMVC

Day7 | Java框架 | SpringMVC SpringMVC简介SpringMVC 概述入门案例入门案例工作流程分析Controller 加载控制与业务bean加载控制&#xff08;SpringMVC & Spring&#xff09;PostMan 请求与响应请求映射路径请求方式&#xff08;不同类型的请求参数&#xff09;&#xff1…

基于JAVA+SpringBoot+Vue的前后端分离企业oa管理系统

基于JAVASpringBootVue的前后端分离企业oa管理系统 前言 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN[新星计划]导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末附源码下载链接&#x1…

信号保存和处理

把上一篇回顾一下吧&#xff1a;共享内存区是最快的IPC形式。一旦这样的内存映射到共享它的进程的地址空间&#xff0c;这些进程间数据传递不再涉及到内核&#xff0c;进程不再通过执行进入内核的系统调用来传递彼此的数据 共享内存的数据结构&#xff1a; struct shmid_ds {…

Vant 按需引入导致 Typescript,eslint 报错问题

目录 1&#xff0c;按需引入问题2&#xff0c;Typescript 报错解决3&#xff0c;eslint 报错解决 1&#xff0c;按需引入问题 vant4 通过 按需引入的配置 使用组件时&#xff0c;会同时将样式也自动导入。所以可直接使用相关的 API 和组件&#xff0c;不会有问题。比如&#x…

Elasticsearch基础(七):Logstash如何开启死信队列

文章目录 Logstash如何开启死信队列 一、确保 Elasticsearch 输出插件启用 DLQ 支持 二、配置 Logstash DLQ 设置 三、查看死信队列 四、排查 CSV 到 Elasticsearch 数据量不一致的问题 Logstash如何开启死信队列 在 Logstash 中&#xff0c;死信队列&#xff08;Dead Le…

QT 联合opencv 易错点

https://blog.csdn.net/qq_51699436/article/details/135777911 网上已经有大量优秀切详尽的文章来讲述QT联合opencv了&#xff0c;我把容易出错的点列出来备忘 1、在进行opencv进行编译时&#xff0c;要确认好是32位还是64位&#xff0c;因为在创建QT项目的时候QT和opencv要匹…

基于R语言的统计分析基础:使用ggplot2包进行绘图

安装ggplot2包并查看官方文档 ggplot2是一个基于图形语法的R包&#xff0c;它允许用户通过声明式方式指定数据、美学映射和图形元素来灵活创建复杂且美观的可视化图表。 ggplot2包官方教学文档&#xff1a;ggplot2官方文档 在R语言中安装ggplot2有两种方法&#xff1a; 安装整…

【自动驾驶】控制算法(八)横向控制Ⅱ | Carsim 与 Matlab 联合仿真基本操作

写在前面&#xff1a; &#x1f31f; 欢迎光临 清流君 的博客小天地&#xff0c;这里是我分享技术与心得的温馨角落。&#x1f4dd; 个人主页&#xff1a;清流君_CSDN博客&#xff0c;期待与您一同探索 移动机器人 领域的无限可能。 &#x1f50d; 本文系 清流君 原创之作&…

GEE 将本地 GeoJSON 文件上传到谷歌资产

在地理信息系统&#xff08;GIS&#xff09;领域&#xff0c;Google Earth Engine&#xff08;GEE&#xff09;是一个强大的平台&#xff0c;它允许用户处理和分析大规模地理空间数据。本文将介绍如何使用 Python 脚本批量上传本地 GeoJSON 文件到 GEE 资产存储&#xff0c;这对…

初识C++|继承

&#x1f36c; mooridy-CSDN博客 &#x1f9c1;C专栏&#xff08;更新中&#xff01;&#xff09; 目录 1. 继承的概念及定义 1.1 继承的概念 1.2 继承定义 1.2.1 定义格式 1.2.2 继承父类成员访问方式的变化 1.3继承类模板 2. 父类和子类对象赋值兼容转换 3. 继承中的…

国内外大模型汇总(包括科大星火、文心一言、通义千问、智普清言、华为大模型)

国内外大模型汇总 1. 科大讯飞星火认知大模型 主要特点&#xff1a; 多语言能力&#xff1a;以中文为核心&#xff0c;同时支持多语言处理&#xff0c;能够进行跨语种的语言理解和生成。 广泛的任务能力&#xff1a;具备内容生成、语言理解、知识问答、推理、数学计算、代码…

数学建模笔记—— 主成分分析(PCA)

数学建模笔记—— 主成分分析 主成分分析1. 基本原理1.1 主成分分析方法1.2 数据降维1.3 主成分分析原理1.4 主成分分析思想 2. PCA的计算步骤3. 典型例题4. 主成分分析说明5. python代码实现 主成分分析 1. 基本原理 在实际问题研究中,多变量问题是经常会遇到的。变量太多,无…

小怡分享之栈和队列

前言&#xff1a; &#x1f308;✨前面小怡给大家分享了顺序表和链表&#xff0c;今天小怡给大家分享一下栈和队列。 1.栈 1.1 概念 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶&#x…

WPF中依赖属性或附加属性的继承

引言 我们可以轻易的编写一个附加属性类&#xff0c;增加任意类型的附加属性并编写一定的逻辑来处理附加值的变化通知。假如控件是我们自定义的一个label、button 、textbox等&#xff0c;自定义控件当然是其他基础类型元素的组合&#xff0c;如shape、line、rectangle、geome…