cesium火箭发射,模型控制,模型动画,模型移动

news2024/11/16 10:30:04

起因:最近想做模型的动画,结果上网查资料,看到网上好多对于模型控制的文章都有限制。决定还是自己研究下。欢迎大家一起探讨,评论留言。

效果

火箭

全部代码在最后

起步

  • 模型控制,第一步当然是需要一个合适的模型,去cesium官网实例中找到了一个合适的模型,并且还顺带了一些模型操作方法。
    在这里插入图片描述

  • 搜索关键字applyArticulations;模型地址;

  • 拿到模型迫不及待的想在自己自己的项目中加载出来

  • 加载方式有两种entityPrimitive, 我个人更喜欢第二种Primitive方式。

  • 对应的参数就不做解释了,文档中都有

let rocketPrimitive: Cesium.Model
let position = Cesium.Cartesian3.fromDegrees(104.200403, 30.396231, 600.0);
const hpRoll = new Cesium.HeadingPitchRoll();
const fixedFrameTransform = Cesium.Transforms.localFrameToFixedFrameGenerator("north", "west");
const rocketPrimitive = viewer.scene.primitives.add(
        Cesium.Model.fromGltf({
            url: "https://assets.agi.com/models/launchvehicle.glb",
            modelMatrix: Cesium.Transforms.headingPitchRollToFixedFrame(
                position,
                hpRoll,
                Cesium.Ellipsoid.WGS84,
                fixedFrameTransform
            ),
            minimumPixelSize: 128,
        })
    );

在这里插入图片描述

模型的组成

const articulations = model.sceneGraph._runtimeArticulations;官方的这段代码我用着报错,文档里面没有。也不知道啥问题

  • 直接将加载的模型打印出来看里面具体的结构

在这里插入图片描述

发现了nodes,模型里面的关节点,就是模型由哪些部分组成,官网文档中也明确的说了。画红线的那段话翻译出来就是"返回glTF中具有给定名称的节点。这用于修改用户定义动画的节点变换"
在这里插入图片描述

模型操作

  • 点火
 rocketPrimitive.setArticulationStage( //对应属性改变参数值
   'SRBFlames Size',
     1
 );
 rocketPrimitive.applyArticulations(); //使得修改的属性生效

在这里插入图片描述

  • 火箭点火后自然就要移动,添加模型的平滑移动,模型的平滑移动我之前的文章有。
  • 原理就是不停的移动模型位置,以及模型的姿态,只要移动的距离足够小看起来就是平滑的。
 Cesium.Transforms.headingPitchRollToFixedFrame(
        showPath[activeIndex], //当前坐标点Cesium.Cartesian3
        hpRoll,//姿态
        Cesium.Ellipsoid.WGS84,
        fixedFrameTransform,
        rocketPrimitive.modelMatrix //模型当前的世界矩阵
    );
  • 利用viewer.scene.preUpdate.addEventListener //下一帧渲染前回调

viewer.scene.preUpdate.addEventListener(keepRun)

  • keepRun 就是我们移动的函数
const keepRun = (scene: Cesium.Scene, time: number) => {
    if (activeIndex >= maxIndex) return
    if (autoDirection && activeIndex > 0 && !showPath[activeIndex - 1].equals(showPath[activeIndex])) { //判断前后两个点是否一样,不一样就调整姿态
        const heading = Helper.getHeading(
            showPath[activeIndex - 1],
            showPath[activeIndex],
        );
        if (heading) hpRoll.heading = heading
        const pitch = Helper.getPitch(
            showPath[activeIndex - 1],
            showPath[activeIndex])
        if (pitch) hpRoll.pitch = pitch
    }
    Cesium.Transforms.headingPitchRollToFixedFrame(
        showPath[activeIndex],
        hpRoll,
        Cesium.Ellipsoid.WGS84,
        fixedFrameTransform,
        rocketPrimitive.modelMatrix
    );
    activeIndex += 1
}

在这里插入图片描述

  • 可以平滑的移动了。

  • 当然火焰的生起也应当平滑,控制模型都需要平滑的操作,直接写个函数控制

function modelAnimationController(controller: typeModelAnimationController) {
    const { type, initVal, maxVal, fn, step, minVal } = controller
    let num = initVal
    let stopFrame: number
    const max = maxVal || 1
    const min = minVal || -99999
    const duration = step || 0.1
    const render = () => {
        num += duration
        rocketPrimitive.setArticulationStage(
            type,
            num
        );
        rocketPrimitive.applyArticulations();
        stopFrame = requestAnimationFrame(render)
        if (num > max || num <= min) {
            window.cancelAnimationFrame(stopFrame)
            fn && fn()
        }
    }
    render()
}
modelAnimationController({
  type: 'SRBFlames Size', initVal: 0, maxVal: 1, step: 0.05, fn: () => {
       viewer.scene.preUpdate.addEventListener(keepRun)
   }
})

在这里插入图片描述

剩下的都是重复的操作,以及反复调试修改达到最佳

  • 比如火焰喷射要有真实感
  • 火箭转向时 喷射头偏转,等等
<template>
    <div class="btn-box">
    </div>
    <Map @onViewerLoaded="onViewerLoaded" :options="options">
    </Map>>
</template>
<script lang="ts" setup>
import Map from "@/components/Cesium/lib/Map.vue";
import * as Cesium from "cesium";
import { GetPosition } from "@/components/Cesium/utils";
import { initLayerPromise } from '@/components/Cesium/utils/initLayer'
import { Helper } from "@/components/Cesium/lib/helper";
let viewer: Cesium.Viewer
const options = {}
let handler: Cesium.ScreenSpaceEventHandler
const onViewerLoaded = (Viewer: Cesium.Viewer) => {
    viewer = Viewer
    handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);

    initLayerPromise(Viewer, true).then(() => {
        viewer.camera.flyTo({
            destination: Cesium.Cartesian3.fromDegrees(104.200403,
                30.396231, 2000),
            // destination: Cesium.Cartesian3.fromDegrees(120.38105869, 31.10115627, 3000),
            complete: () => { init() }
        });
        // init()
    })
    const getP = new GetPosition(Viewer);
    getP.getPositionByClick((position: any) => {
        console.log(position);
    });
};
let planePrimitive: Cesium.Model
let position = Cesium.Cartesian3.fromDegrees(104.200403, 30.396231, 600.0);
const hpRoll = new Cesium.HeadingPitchRoll();
const fixedFrameTransform = Cesium.Transforms.localFrameToFixedFrameGenerator("north", "west");

let activeIndex = 0 //插值经纬度索引
let maxIndex = 0// 最大插值经纬度数组索引
let autoDirection = true; //自动调整方向
let path: [number, number, number][] = [] //存在路线数组
let showPath: Cesium.Cartesian3[] = [] //插值数组
let camera: Cesium.Camera
let controller: Cesium.ScreenSpaceCameraController
let r: number
const hpRange = new Cesium.HeadingPitchRange();
let nodes: any[] = []
const init = () => {
    hpRoll.pitch = 90 * Math.PI / 180;
    planePrimitive = viewer.scene.primitives.add(
        Cesium.Model.fromGltf({
            url: "models/launchvehicle.glb",
            modelMatrix: Cesium.Transforms.headingPitchRollToFixedFrame(
                position,
                hpRoll,
                Cesium.Ellipsoid.WGS84,
                fixedFrameTransform
            ),
            minimumPixelSize: 128,
        })
    );
    const scene = viewer.scene;
    planePrimitive.readyPromise.then((model) => {
        camera = viewer.camera;
        controller = scene.screenSpaceCameraController;
        r =
            2.0 * Math.max(model.boundingSphere.radius, camera.frustum.near);
        controller.minimumZoomDistance = r * 0.2;
        /**
         modelAnimationController({
            type: 'SRBFlames Size', initVal: 0, maxVal: 1, step: 0.05, fn: () => {
                modelAnimationController({ type: 'SRBFlames Size', initVal: 1, minVal: 0, step: -0.5 })
                modelAnimationController({
                    type: 'SRBs Separate', initVal: 0, maxVal: 10, step: 0.5, fn: () => {//一级脱落
                        modelAnimationController({ type: 'SRBs Drop', initVal: 0, minVal: -50, step: -0.5 })
                    }
                })
                // modelAnimationController({ type: 'BoosterEngines Yaw', initVal: 0, maxVal: 1, step: 0.1 }) //左右
                // modelAnimationController({ type: 'BoosterEngines Pitch', initVal: 0, maxVal: 1, step: 0.1 }) //上下
                modelAnimationController({
                    type: 'BoosterFlames Size', initVal: 0, maxVal: 1, step: 0.1, fn: () => {
                        modelAnimationController({ type: 'Fairing Open', initVal: 0, maxVal: 45, step: 0.5 })
                        modelAnimationController({ type: 'Fairing Separate', initVal: 0, minVal: -10, step: -0.1 })
                        modelAnimationController({ type: 'Fairing Drop', initVal: 0, minVal: -50, step: -0.5, fn: ()=> {
                            //主推进器脱落
                            modelAnimationController({ type: 'Booster MoveZ', initVal: 0, minVal: -50, step: -0.5})
                            modelAnimationController({ type: 'UpperStageFlames Size', initVal: 0, maxVal: 1, step: 0.05, fn:()=> {
                                modelAnimationController({ type: 'InterstageAdapter MoveZ', initVal: 0, minVal: -50, step: -0.5})
                            }})
                            // modelAnimationController({ type: 'UpperStageEngines Yaw', initVal: 0, maxVal: 1, step: 0.05,})//左右
                            // modelAnimationController({ type: 'UpperStageEngines Pitch', initVal: 0, maxVal: 1, step: 0.05,}) //上下
                        } })
                    }
                })
            }
        })
         */
        lookAt()
        pickup()
        nodes = planePrimitive.gltf.nodes
        // nodes.forEach(i => {
        //     if (new RegExp(/InterstageAdapter/).test(i.name)) {
        //         planePrimitive.getNode(i.name).show = false
        //     }
        // })

        crateLine().then(() => {
            modelAnimationController({
                type: 'SRBFlames Size', initVal: 0, maxVal: 1, step: 0.05, fn: () => {
                    viewer.scene.preUpdate.addEventListener(keepRun)
                }
            })
        })
    })

}
function pickup() {
    handler.setInputAction(function (movement) {
        const pickedObject = viewer.scene.pick(movement.position);
        if (Cesium.defined(pickedObject)) {
            console.log(pickedObject)
        }
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
}
const lookAt = () => {
    const center = Cesium.Matrix4.multiplyByPoint(
        planePrimitive.modelMatrix,
        Cesium.Cartesian3.ZERO,
        new Cesium.Cartesian3()
    );
    const heading = Cesium.Math.toRadians(10.0);
    const pitch = Cesium.Math.toRadians(-5.0);
    camera.lookAt(
        center,
        new Cesium.HeadingPitchRange(heading, pitch, r * 2)
    );
}
type typeModelAnimationController = {
    type: string;
    initVal: number;
    maxVal?: number;
    minVal?: number;
    fn?: Function;
    step?: number,
}
function modelAnimationController(controller: typeModelAnimationController) {
    const { type, initVal, maxVal, fn, step, minVal } = controller
    let num = initVal
    let stopFrame: number
    const max = maxVal || 1
    const min = minVal || -99999
    const duration = step || 0.1
    const render = () => {
        num += duration
        planePrimitive.setArticulationStage(
            type,
            num
        );
        planePrimitive.applyArticulations();
        stopFrame = requestAnimationFrame(render)
        if (num > max || num <= min) {
            window.cancelAnimationFrame(stopFrame)
            fn && fn()
        }
    }
    render()
}
const crateLine = () => {
    const lon = 104.200403, lat = 30.396231, alt = 20600
    for (let index = 1; index < 20; index++) {
        path.push([lon, lat, 600 + 1000 * index])
    }
    const len = 1000
    let lastLat = 0, lastLon = 0, lastAlt = 0, activeLon, activeLat, activeAlt
    for (let index = 0; index < len; index++) {
        activeLon = Number((lon + index * 0.01).toFixed(6))
        activeLat = Number((lat + index * 0.02).toFixed(6))
        activeAlt = alt + index * 1000
        path.push([activeLon, activeLat, activeAlt])
        if (index === len - 1) {
            lastLon = activeLon
            lastLat = activeLat
            lastAlt = activeAlt
        }
    }
    for (let i = 0; i <= 360; i += 1) {
        path.push([lastLon + i, lastLat, lastAlt])
    }
    return new Promise(resolve => {
        getPosition().then(res => {
            showPath = res
            maxIndex = res.length
            const line = viewer.scene.primitives.add(
                new Cesium.Primitive({
                    geometryInstances: new Cesium.GeometryInstance({
                        geometry: new Cesium.PolylineGeometry({
                            positions: res,
                            width: 3.0,
                            vertexFormat: Cesium.PolylineColorAppearance.VERTEX_FORMAT,
                        }),
                        attributes: {
                            color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.BLUE.withAlpha(.7)),
                        },
                    }),
                    appearance: new Cesium.PolylineColorAppearance(),
                })
            );
            line.readyPromise.then(() => {
                resolve('')
            })
        })
    })
}

const keepRun = (scene: Cesium.Scene, time: number) => {
    if (activeIndex >= maxIndex) return
    console.log(activeIndex)
    if (activeIndex === 1000) {
        modelAnimationController({ type: 'SRBFlames Size', initVal: 1, minVal: 0, step: -0.5 })
        modelAnimationController({
            type: 'SRBs Separate', initVal: 0, maxVal: 10, step: 0.5, fn: () => {//一级脱落
                modelAnimationController({
                    type: 'SRBs Drop', initVal: 0, minVal: -100, step: -1, fn: () => nodes.forEach(i => {
                        if (new RegExp(/SRB\d/).test(i.name)) {
                            planePrimitive.getNode(i.name).show = false
                        }
                    })
                })
            }
        })
        modelAnimationController({ type: 'BoosterFlames Size', initVal: 0, maxVal: 1, step: 0.1 }) //主推期开始点火
    }
    if (activeIndex === 3000) {
        modelAnimationController({ type: 'Fairing Open', initVal: 0, maxVal: 45, step: 0.5 })
        modelAnimationController({ type: 'Fairing Separate', initVal: 0, minVal: -10, step: -0.1 })
        modelAnimationController({
            type: 'Fairing Drop', initVal: 0, minVal: -150, step: -1, fn: () => {
                //主推进器脱落
                modelAnimationController({ type: 'BoosterFlames Size', initVal: 1, minVal: 0, step: -0.05 })
                modelAnimationController({
                    type: 'Booster MoveZ', initVal: 0, minVal: -150, step: -1, fn: () => {
                        nodes.forEach(i => {
                            if (new RegExp(/Fairing\d/).test(i.name) || new RegExp(/Booster/).test(i.name)) {
                                planePrimitive.getNode(i.name).show = false
                            }
                        })
                    }
                })
                modelAnimationController({ type: 'UpperStageFlames Size', initVal: 0, maxVal: 1, step: 0.05 })
            }
        })
    }
    if (activeIndex === 3600) {
        modelAnimationController({
            type: 'InterstageAdapter MoveZ', initVal: 0, minVal: -150, step: -1, fn: () => {
                nodes.forEach(i => {
                    if (new RegExp(/InterstageAdapter/).test(i.name)) {
                        planePrimitive.getNode(i.name).show = false
                    }
                })
            }
        })
    }
    lookAt()
    if (autoDirection && activeIndex > 0 && !showPath[activeIndex - 1].equals(showPath[activeIndex])) {
        const heading = Helper.getHeading(
            showPath[activeIndex - 1],
            showPath[activeIndex],
        );
        if (heading) hpRoll.heading = heading
        const pitch = Helper.getPitch(
            showPath[activeIndex - 1],
            showPath[activeIndex])
        if (pitch) hpRoll.pitch = pitch
    }
    Cesium.Transforms.headingPitchRollToFixedFrame(
        showPath[activeIndex],
        hpRoll,
        Cesium.Ellipsoid.WGS84,
        fixedFrameTransform,
        planePrimitive.modelMatrix
    );
    activeIndex += 1
}
const getPosition = () => {
    //插值 new Cesium.LinearSpline  new Cesium.CatmullRomSpline esium.HermiteSpline.createNaturalCubic
    //let pos = Cesium.Cartesian3.lerp(startP, endP, i / duration, new Cesium.Cartesian3());
    return new Promise((resolve: (value: Cesium.Cartesian3[]) => void) => {
        const points = path.map(i => Cesium.Cartesian3.fromDegrees(...i))
        let times: number[] = []
        for (let index = 0; index < points.length; index++) {
            times.push(index)
        }
        const spline = new Cesium.CatmullRomSpline({
            points,
            times,
        });
        const positions: Cesium.Cartesian3[] = [];
        for (let i = 1; i < times.length; i++) {
            for (let j = 0; j < 100; j++) {
                const cartesian3 = spline.evaluate(i - 1 + j * 0.01);
                positions.push(cartesian3);
            }
        }
        resolve(positions)
    })
}
</script>
<style lang="less" scoped>
.btn-box {
    position: absolute;
    top: 10px;
    z-index: 10;
    width: 500px;
    margin-left: 20px;
}
</style>

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

链动2+1模式是否合法合规?它涉及多级传销吗?

根据国家《禁止传销条例》第2条规定&#xff0c;传销是指组织者或者经营者发展人员&#xff0c;通过对被发展人员以其直接或者间接发展的人员数量或者销售业绩为依据计算和给付报酬&#xff0c;或者要求被发展人员以交纳一定费用为条件取得加入资格等方式牟取非法利益&#xff…

【多线程】Thread的interrupt()

一、前言 如果子线程执行完毕终止状态&#xff0c;主线程再去调用interrupt()有什么效果&#xff1f;如果子线程还在执行过程中&#xff0c;主线程调用interrupt()有什么结果&#xff1f; 二、模拟实验 1、模拟子线程执行完毕再调用interrupt() ​ public class Test {publi…

2023年天津美术学院专升本报名考试须知

天津美术学院2023年高职升本科报考须知&#xff08;一&#xff09;专业考试1.报名方法&#xff1a; ①网上报名及缴费&#xff1a; 我校采取网上报名的方式,考生于2022年12月份&#xff08;具体时间关注公众号“高职接本科”另行公告&#xff09;(10:00-22:00)登录网站(网址&am…

web前端期末大作业 html+css学生心理 7页主题网页设计

⛵ 源码获取 文末联系 ✈ Web前端开发技术 描述 网页设计题材&#xff0c;DIVCSS 布局制作,HTMLCSS网页设计期末课程大作业 | 家 | HTML期末大学生网页设计作业 HTML&#xff1a;结构 CSS&#xff1a;样式 在操作方面上运用了html5和css3&#xff0c; 采用了divcss结构、表单、…

Oculus Deeplink

DeepLink 初始化 platform sdk 后设置 应用启动回调判断应用打开的方式发起应用跳转 接收应用跳转 GroupPresence 本文档基于 GroupPresenceSample 脚本逻辑编写&#xff0c;展示通过群组状态发起用户邀请&#xff0c;以及响应对应回调。参考 Oculus 工程 SharedSpaces 使…

【安装教程】vscode安装教程(超详细)

Visual Studio Code&#xff08;简称 VSCode&#xff09;是一款由微软开发且跨平台的免费源代码编辑器。该软件支持语法高亮、代码自动补全、代码重构功能&#xff0c;并且内置了命令行工具和 Git版本控制系统。用户可以更改主题和键盘快捷方式实现个性化设置&#xff0c;也可以…

想裁剪视频时长,用电脑怎么裁剪视频时长

大家有没有碰到过这种一种情况&#xff0c;就是我们在社交平台上发布视频时&#xff0c;会因为视频时长过长这个问题而导致视频发布失败。那我们要怎么处理这个问题呢&#xff1f;其实我们可以使用一些剪辑软件&#xff0c;将视频裁剪&#xff0c;只截取视频里面较为精彩的部分…

hadoop集群安装(三):创建同步工具并安装jdk

文章目录说明分享环境创建同步工具编写脚本设置为系统命令安装jdk总结说明 搭建好集群虚拟机&#xff0c;新建同步工具并安装jdk&#xff0c;同步工具方便管理集群&#xff0c;某些操作和一条命令&#xff0c;同步所有节点&#xff0c;增加集群操作效率。 分享 大数据博客列表…

组件之间通过bus中央事件总线进行通信

案例完整代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widt…

66. SAP ABAP Function Module 的动态调用方式使用方式介绍

在本教程前面的步骤 7,我们介绍了 ABAP Function Module 的基本使用方法: 7. ABAP function module 的使用最近我的知识星球有朋友提问: 大佬,我想问一下动态获取到物料主数据的字段名之后,如何将获取到的字段名去与bapi中的字段名对应起来从而去修改物料主数据中对应的字…

多维时序 | MATLAB实现CNN-GRU多变量时间序列预测

多维时序 | MATLAB实现CNN-GRU多变量时间序列预测 目录多维时序 | MATLAB实现CNN-GRU多变量时间序列预测基本介绍模型特点程序设计学习总结参考资料基本介绍 本次运行测试环境MATLAB2020b&#xff0c;MATLAB实现CNN-GRU多变量时间序列预测&#xff0c;卷积门控循环单元。 模型特…

ComponentAce FlexCompress强大功能

ComponentAce FlexCompress强大功能 FlexCompress是一个高速压缩库&#xff0c;旨在为您的应用程序提供归档功能。此解决方案提供了灵活的压缩和强大的加密算法&#xff0c;使您可以快速轻松地将归档或备份功能集成到程序中。 FlexCompress包括我们新的独特技术&#xff0c;即交…

分片架构设计技巧

Elasticsearch集群设计技巧 ES的基本架构 节点可以配置为不同角色&#xff0c;通过选举Master管理集群Coordinating&#xff1a;协调节点&#xff1b;Master&#xff1a;管理节点&#xff1b;Data&#xff1a;数据存储节点 数据是按照索引分片的&#xff0c;而不是按照节点分片…

在C#方法中 out、ref、in、params 关键字的用法

out&#xff1a;关键字&#xff1a; 指定的参数在进入函数时会清空自己&#xff0c;必须在函数内部赋初值 ref关键字&#xff1a; 指定的参数必须在进入函数时赋初值&#xff0c;在函数内部可以重新赋值 In关键字&#xff1a; 指定的参数必须在进入函数时赋初值&#xff0c;…

MySQL进阶篇(五)- 锁

一、概述&#xff08;P121&#xff09; 锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中&#xff0c;除传统的计算资源&#xff08;CPU、 RAM、I/O&#xff09;的争用以外&#xff0c;数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有效性…

51、部署PaddleSeg的pp_liteseg到MNN框架、OpenVINO框架和OAK框架、NPU(RK3399 PRO)框架

基本思想&#xff1a;需要一个快的实例分割模型&#xff0c;由于需要配置oak使用&#xff0c;所以就记录和实现一下微软社区提供的思路&#xff0c;去部署PaddleSeg的轻量级(实际是语义)分割模型 所有的实验模型&#xff0c;花了两天。。。mmp 自己训练模型&#xff0c;开始整…

[附源码]java毕业设计药品销售管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

【AI】浅谈梯度下降算法(理论篇)

前言 在求解机器学习算法的模型参数&#xff0c;即无约束优化问题时&#xff0c;梯度下降&#xff08;Gradient Descent&#xff09; 是最常采用的方法之一&#xff0c;另一种常用的方法是最小二乘法。 目前正在学习这方面相关的内容&#xff0c;因此简单谈谈与梯度下降法相关…

13T搅拌运输车冷却系统改进设计

目 录 摘 要 1 Abstract 2 1绪论 5 1.1选题背景及意义 5 1.2研究现状 6 1.2.1 影响13T混凝土搅拌运输车冷却系统的因素以及目前存在的问题 6 1.2.2目前存在的问题 6 1.2.3现代冷却系统研究现状及发展方向 7 1.3研究主要内容 8 2 13T混凝土搅拌运输车冷却系统组成功用和选型 9 2…

m基于PTS+TR的OFDM系统PAPR联合抑制算法matlab仿真

目录 1.算法描述 2.仿真效果预览 3.MATLAB部分代码预览 4.完整MATLAB程序 1.算法描述 部分传输序列(Partial Transmit Sequence , PTS)由于其不受载波数量限制&#xff0c;并且能够有效的&#xff0c;无失真的降低OFDM信号峰均比&#xff0c;而受到广泛关注。部分传输序列算…