Ceisum无人机巡检视频投放

news2024/12/27 11:34:17

公司投标内容有个视频投放的功能动画,原本想实现这么一个效果:
在这里插入图片描述
案例效果来自别人的展示作品,Leader一眼就相中了这个效果,可惜别人的终究是别人的,又不会白白给你,终究是要自己动手尝试。

动画方面的展示效果我已经非常熟练了,无非就是两种写法1. 实体绑定时间轴,监听路径以及姿态;2. CZML加载模型和点位集合。
为了方便,我一般都用第二种。动画方面没有问题,那么就差一个视椎体视频了,只要把这个做出来,把它跟CZML的时间轴绑定起来就完事了。

Step 0:
思路:构建一个视椎体,然后计算远截面四点坐标,利用这四个点来画一个矩形,贴入视频材质,完成视频在视椎体内播放。
使用CZML播放动画,将视椎体的朝向更正为垂直向下,再将位置绑定给动画中的实体,让它们一起运动。
在这里插入图片描述
经过不懈努力拿到一个视椎体方法,可以计算出四点点位,视频作为材质镶嵌到视椎体头部,偶然间尝试到的perPositionHeight: true解决了多边形不贴合问题,视频播放也解决了,一切都在向着美好的方向,最后发现视椎体我控制不了它旋转到垂直向下的方向,这需要足够的矩阵计算能力,还有就是动态更新位置也是个技术大关,一时半会儿搞不定,Game Over!

花费了不少时间去追求最高品质效果,受阻后开始琢磨阉割版。

虽然接下来实现的可能是个简陋功能,但能让Leader有个可以交差的东西,后续有时间再重新研究。

想法:去除视椎体,添加一个适合贴视频的材质,让它跟随无人机一起运动,可以简单实现视频追着无人机飞。

Step 1:
思路: 动态点还是依靠CZML实现,在dataSource.then方法内部作用域中获取路径实体,添加rectangle矩形,所需四个点通过Cesium.CallbackProperty回调函数实时计算。

部分代码:

dataSource
        .then(function (dataSource) {
          var entity = dataSource.entities.getById("path");
          entity.viewFrom = new Cesium.Cartesian3(0.0, 0, 15000.0);
          that.viewer.trackedEntity = entity;
	
	const videoElement = document.getElementById('ceguiji'); //视频早已绑定到标签
          that.viewer.entities.add({
              rectangle: {
                  coordinates: new Cesium.CallbackProperty(function (time, result){
                    var sourpos = entity.position.getValue(time);
                    var cartographic1 = Cesium.Ellipsoid.WGS84.cartesianToCartographic(sourpos);
                    var lon1 = Cesium.Math.toDegrees(cartographic1.longitude);
                    var lat1 = Cesium.Math.toDegrees(cartographic1.latitude);
                    var height1 = cartographic1.height;
                    return Cesium.Rectangle.fromDegrees(lon1-0.0001,lat1 - 0.0002, lon1+0.0001, lat1+0.0002)
                  },false),
                  material: videoElement
              },
          })

	}

在这里插入图片描述

很容易就出来一个跟随路径飞行的视频,但跟路径夹角基础在45度,视频长宽被拉伸得不成型,还不能变方向,这就是固定点的局限性,直接pass。

Step 2:
思路:将材质换成视频墙,plane比wall更合适,只需要一个动点,长宽皆可由属性定义,这样一个长宽合适的视频就跟随路径移动了,但有个两个问题,一个是大难题怎样实时更新姿态,另一个视频立起来了,我还要让它倒下去,跟地面平行。

部分代码:

var bluePlane = that.viewer.entities.add({
            name : "Blue plane",
            position : Cesium.Cartesian3
                .fromDegrees(118.835100, 35.183068, 190),
            plane : {
              plane : new Cesium.Plane(Cesium.Cartesian3.UNIT_Y, 0.0),
              dimensions : new Cesium.Cartesian2(-150.0, 100.0),
              material : videoElement,
              stRotation: Cesium.Math.toRadians(90)
            },
          });

在这里插入图片描述

经过一系列尝试,我发现解决将它放平的难度可能比解决实时更新姿态的难度更高,AI也说了,这两个材质设计之初就没考虑过空间问题,所以还是换吧。

Step 3:
思路:box材质让我看到了希望,它是一个立体盒子,我可以通过设置长宽、高为0,来实现一个平面视频墙。

var bluePlane = that.viewer.entities.add({
            name : "Blue plane",
            position : Cesium.Cartesian3
                .fromDegrees(118.835100, 35.183068, 190),
            box: {
              dimensions : new Cesium.Cartesian3(60.0, 30.0, 0.0),
              material: videoElement
            },
          });

在这里插入图片描述

轻松得到一个平行地面的视频材质,所以只剩下最后一个问题,如何让材质跟随路径调整姿态。

Step 4:
思路:我尝试将box加入czml中,这样它可以通过czml的自带属性来实时更新姿态,我就不用考虑变换矩阵

{
            id: "box",
            name: "uva-box-fly",
            availability: "2022-08-04T10:00:00Z/2022-08-04T15:00:00Z",
            box: {
                dimensions: {
                    cartesian: [60.0, 30.0]
                },
                material: Cesium.Color.RED.withAlpha(0.5),
            },
            orientation: {
                velocityReference: "#position"
            },
            model: {
                gltf: "/models/Cesium_Air.glb",
                scale: 2
            },
            position: {
                epoch: "2022-08-04T10:00:00Z",
                cartographicDegrees: [],
            },
        },

但我发现视频是横着放的,这个暂且不管,得到下面这个效果。
在这里插入图片描述
因为它用的是飞机路径的position,和飞机路线重合,所以就叠一起了,我复制了一份路径存储数组,在push的时候高度降低50,这样就可以分离飞机和视频。

但再看效果,发现连飞机都复刻下来了,简直离谱!
在这里插入图片描述
Step 5:
接上一步,既然都是要在dataSource.then中实现,那么加入实体追踪的方式似乎也难不了多少,尝试了一下思路,很轻易就实现了同样的效果,关键点在于设置实体方向orientation: Cesium.Quaternion.IDENTITY,这个值可以根据position初始化姿态,也就可以做到跟随路径同步调整方向,但实现效果上我看到了一个斜放的刀片一样的东西,视频方向永远倾斜,这跟视椎体初始化角度问题一样,是个大毛病。
在这里插入图片描述

看到只差最后一步,我只能去搜寻旋转实体的方法,让它在原有姿态基础上旋转到合适角度。原本尝试了Cesium.Transforms.headingPitchRollQuaternion(Cesium.Cartesian3.fromDegrees(lon,lat,height), new Cesium.HeadingPitchRoll(45, 0, 0))这个常用办法,但报错了,搜了一下AI发现这个用于局部坐标系,而我获取到的点已经是Cartesian3,方法不可用,于是尝试更难的四元数矩阵转换,还好没给我出现太多阻碍,连着解决了几个小问题,实现了比较好的一版。

部分代码:

var bluePlane = that.viewer.entities.add({
                name : "Blue plane",
                position : Cesium.Cartesian3
                    .fromDegrees(118.835100, 35.183068, 190),
                orientation: Cesium.Quaternion.IDENTITY,
                box: {
                    dimensions : new Cesium.Cartesian3(60.0, 30.0, 0.0),
                    material: videoElement
                },
            });

            that.viewer.clock.onTick.addEventListener(function(clock) {
                var currentTime = that.viewer.clock.currentTime;
                var currentOrientation = entity.orientation.getValue(currentTime);
                if (Cesium.defined(currentOrientation) && currentOrientation instanceof Cesium.Quaternion) {
                    var newOrientation = Cesium.Quaternion.clone(currentOrientation);
                    // 应用旋转
                    var rotationQuaternion = Cesium.Quaternion.fromAxisAngle(Cesium.Cartesian3.UNIT_Z, Cesium.Math.toRadians(-90));
                    var finalOrientation = Cesium.Quaternion.multiply(newOrientation, rotationQuaternion, new Cesium.Quaternion());
                    // 更新实体的 orientation
                    bluePlane.orientation = new Cesium.ConstantProperty(finalOrientation);
                } else {
                    console.error('Orientation is not a valid Cesium.Quaternion');
                }
            })

            var property = new Cesium.SampledPositionProperty();//存储坐标
            for (var ind = 0; ind < timesArr.length; ind++) {
                var time = Cesium.JulianDate.addSeconds(
                    that.viewer.clock.currentTime,
                    timesArr[ind],
                    new Cesium.JulianDate()
                );
                var position = entity.position.getValue(time);
                if (position) {
                    var cartographic =
                        Cesium.Ellipsoid.WGS84.cartesianToCartographic(position);
                    var lat = Cesium.Math.toDegrees(cartographic.latitude);
                    var lng = Cesium.Math.toDegrees(cartographic.longitude);
                    var hei = cartographic.height / 1.9;

                    property.addSample(
                        time,
                        Cesium.Cartesian3.fromDegrees(lng, lat, hei)
                    );
                }
            }
            bluePlane.position = property;

在这里插入图片描述
效果我很满意,实现了我最初的思路,视频和无人机保持相对静止状态,同时飞行和调整朝向,视频可以播放,于是迫不及待地写入了项目。
在这里插入图片描述
阉割版视频投屏正式完成了,Leader可以拿去交差了。

两个月后。。。

Leader找到我,问我视频投放这块有什么突破性研究没有,可不可以把之前看到的那个高品质效果做出来,我给了他一个OK的手势。

我在来到这个公司之前,是做军工项目的,对于Cesium用的最多的就是军标绘制,兵力单元的展示等静态方面的效果,交互用的不多,视椎体更是不了解。

在那次受挫之后,我看了很多计算机图形学的文章,搜罗了网上几乎所有对相机视椎体的介绍文章,还从地理专业的高中同学以及考研的大学室友那里取了经,自信已经可以试着把那个功能做出来了。

之前还遗留了个问题,就是关于视椎体为什么会歪的答案,我请教了Cesium中文网的作者,他告诉我视椎体初始姿态会受到地理位置的影响,需要手动矫正。后来我结识了很多Cesium爱好者,互相分享技术,探讨问题,终于在某个Demo中拿到了矫正过的视椎体,虽然方法被做过加密,里面全是单个字母那种变量,让人看的头晕,但我还是将矫正方法给剥离了出来,加入了我的视椎体中,但很神奇的一点,人家可以完美运行的方法,到了我这就不断报错,我逐行检查,发现了几个NaN,原来是计算过程中出现了不符合数学逻辑的东西,由于没找到罪魁祸首,我暂且在中间强行赋值,跳过了几步,让视椎体正常构建而不报错,最后成功矫正了朝向,但也留了个问题,想要在视椎体构建完成之后再次改动朝向,需要重新矫正视椎体,我用的暴力矫正方法可没那么灵活。

不要想太多,先把功能给实现再说,细节方面可以慢慢来。

我重新构建了视椎体,贴上视频,计算出远截面四顶点相对位置,构建平移矩阵移动位置,构建旋转矩阵调整朝向,很好,都成功了,接着加载CZML动画,将视椎体的中心点给绑了上去,视椎体其他部位都是根据中心点来自动调整的。

就在我满含期待之下,纳尼?视椎体不见了?

就在CZML启动之后,视椎体瞬移消失了,我根本不知道它跑哪儿去了,我询问了一些Cesium爱好者,他们说可能是没有考虑缩放等属性,导致视椎体变得很小或者处于隐身状态。

对此我毫无办法,我的能力目前只到这里,超出平移和旋转的知识还是两眼一抹黑,我心想难到就止步于此了吗?

不!我可不是一个人,我的背后还有一支完备的支援大军,我有一个Cesium探讨扣扣群,里面的个个都是人才,说话又好听,于是就将我的问题抛给了群友,期待能从他们那里得到答案。

答案并没有如期拿到,因为群里的老大哥不屑地告诉我,视频投影?群文件里早就上传的有,你干嘛再自己做一个?

于是我找到了那个源码,如获至宝,居然是封装完好的,可以直接拿来用,于是我就改变思路,在这个封装方法的基础上继续完成我的无人机视频投放。封装的方法只到改变初始姿态这点,后面的都要我自己加上,但这对我而言完全不是问题,很快我就看到了效果。
在这里插入图片描述在这里插入图片描述

感谢群友的贡献,功能真的很完美,效果跟Leader相中的那个案例作品差不多。
视频投影源码是别人的成果,我就不私自放了。

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

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

相关文章

Spring:Bean(创建方式,抽象继承,工厂Bean,生命周期)

1&#xff0c;Bean的创建 1.1&#xff0c;调用构造器创建Bean 调用Bean类的无参构造函数来创造对象&#xff0c;因此要求提供无参构造函数。在这种情况下class元素是必须的&#xff0c;值就是Bean对象的实现类。 如果采用设值注入&#xff0c;Spring容器将使用默认的构造器来创…

ViT面试知识点

文章目录 VITCLIPBlipSAMLSegFast TransformerYOLO系列问题 BatchNorm是对一个batch-size样本内的每个特征做归一化&#xff0c;LayerNorm是对每个样本的所有特征做归一化。 Layer Normalization&#xff08;层归一化&#xff0c;简称LayerNorm&#xff09;是一种在深度学习中…

了解数据库并发产生的问题

在数据库管理系统中&#xff0c;并发控制是一个至关重要的方面。随着多个用户或进程同时访问和修改数据库中的数据&#xff0c;如果没有适当的并发控制机制&#xff0c;就可能导致数据不一致、丢失更新、脏读、不可重复读和幻读等问题。在单用户系统中&#xff0c;数据库操作是…

qt QFontDialog详解

1、概述 QFontDialog 是 Qt 框架中的一个对话框类&#xff0c;用于选择字体。它提供了一个可视化的界面&#xff0c;允许用户选择所需的字体以及相关的属性&#xff0c;如字体样式、大小、粗细等。用户可以通过对话框中的选项进行选择&#xff0c;并实时预览所选字体的效果。Q…

【JavaSE】(2) 方法

一、认识方法 1. 方法的定义 修饰符 返回类型 方法名(形参类型 形参名, ......){......return 返回值; } 示例代码&#xff1a; 2. 方法的作用 增强代码的可复用性。&#xff08;避免重复造轮子&#xff09;增强代码的易管理性。&#xff08;改方法就行&#xff0c;不用到处…

享元模式及其运用场景:结合工厂模式和单例模式优化内存使用

介绍 享元模式&#xff08;Flyweight Pattern&#xff09;是一种结构型设计模式&#xff0c;它通过共享对象来减少内存使用&#xff0c;尤其是对于大量相似对象的场景。享元模式通常与工厂模式和单例模式结合使用&#xff0c;从而有效地控制和复用对象的创建。在享元模式中&am…

【RabbitMQ】03-交换机

1. 交换机 2. Fanout交换机 广播。生产者向exchange发消息 SpringBootTest public class SpringAmqpTest {Autowiredpublic RabbitTemplate rabbitTemplate;Testvoid testSimple() {String exchangName "hmall.fabout";rabbitTemplate.convertAndSend(exchangName…

【赵渝强老师】安装部署Memcached

Memcached是一个高性能的分布式的内存对象缓存系统。通过使用Memcached可以支持高负载的网站系统&#xff0c;以分担数据库的压力。Memcached通过在内存里维护一个统一的巨大的Hash表来存储各种格式的数据&#xff0c;包括图像、视频、文件以及数据库检索的结果等。但是Memcach…

代码要走的路:编程“三部曲”

代码要成为可以运行的程序&#xff0c;总共有3步&#xff1a; 1&#xff0e;编辑&#xff08;edit&#xff09; 这里的编辑不是像出版编辑那样&#xff0c;只把现成的东西修修改改&#xff0c;而是指编写代码。 编写代码是实实在在的原创&#xff0c;不是整理加工&#xff0…

支持向量机相关证明 解的稀疏性

主要涉及拉格朗日乘子法&#xff0c;对偶问题求解

漫途焊机安全生产监管方案,提升安全生产管理水平!

随着智能制造时代的到来&#xff0c;企业安全生产管理的重要性日益凸显。特别是在现代工厂中&#xff0c;焊机的安全生产监管成为了一个不容忽视的重要环节。传统的焊机安全生产监管方式存在诸多不足&#xff0c;如人工巡检频率低、数据延迟、安全隐患发现不及时等问题。因此&a…

【dvwa靶场:XSS系列】XSS (Reflected)低-中-高级别,通关啦

一、低级low 简单拿捏 <script>alert(123)</script>二、中级middle 源码过滤了script但是没有过滤大小写&#xff0c;改成大写S <Script>alert(123)</script>三、高级high 比中级高&#xff0c;过滤了script并且以及大小写&#xff0c;使用其他标…

太速科技-634-基于3U PXIe的VU3P FMC+数据接口板

基于3U PXIe的VU3P FMC数据接口板 一、产品概述 板卡是一款基于 3U PXIE 总线架构的高性能数据预处理FMC 载板&#xff0c;具有 1 个 FMC&#xff08;HPC&#xff09;接口&#xff0c;1 个 X8 GTH 背板互联接口&#xff0c;可以实现 1 路 PCIe x8。板卡主控芯片采用Xilin…

【LLM Agents体验】Dify框架的安装指南

Dify简介&#xff1a; 核心功能‌12 ‌Dify是一款开源的大语言模型(LLM)应用开发平台&#xff0c;融合了后端即服务&#xff08;Backend as a Service, BaaS&#xff09;和LLMOps的理念&#xff0c;使开发者可以快速搭建生产级的生成式AI应用。LLMOps涵盖了大型语言模型的开发、…

推荐一款PowerPoint转Flash工具:iSpring Suite

iSpring Suite是一款PowerPoint转Flash工具&#xff0c;使用iSpring Suite 8可以轻松的将PPT演示文档转换为对Web友好的Flash影片格式。软件界面简洁&#xff0c;使用方便。为什么要转换成flash格式呢?Flash格式的最大特点是体积小巧、易于分发&#xff0c;兼容所有的操作系统…

数据库->视图

目录 一、视图 1.什么是视图 ​编辑 2.创建视图 1.语法 3.使用视图 4.视图的功能 1.屏蔽相关字段 2.对外提供统一访问规范 3.视图和真实表进行表连接查询 5.修改数据 6.注意事项 7.删除视图 1.语法 8.视图的优点 1. 简单性 2. 安全性 3. 逻辑数据独⽴性 4. 重…

影响神经网络速度的因素- FLOPs、MAC、并行度以及计算平台

影响神经网络速度的四个主要因素分别是 FLOPs&#xff08;浮点操作数&#xff09;、MAC&#xff08;内存访问成本&#xff09;、并行度以及计算平台。这些因素共同作用&#xff0c;直接影响到神经网络的计算速度和资源需求。 1. FLOPs&#xff08;Floating Point Operations&a…

Java Development Kit (JDK) 详解

什么是 JDK&#xff1f; JDK 是 Java Development Kit 的缩写&#xff0c;是一组用于开发 Java 应用程序的软件开发工具和库的集合。JDK 包含了 Java 运行时环境&#xff08;JRE&#xff09;和 Java 虚拟机&#xff08;JVM&#xff09;&#xff0c;以及一系列开发工具和库。 …

Rust 力扣 - 1652. 拆炸弹

文章目录 题目描述题解思路题解代码题目链接 题目描述 题解思路 我们只需要遍历长度长度为k的窗口&#xff0c;然后把窗口内数字之和填充到结果数组中的对应位置即可 题解代码 impl Solution {pub fn decrypt(code: Vec<i32>, k: i32) -> Vec<i32> {let n c…

AAA 数据库事务隔离级别及死锁

目录 一、事务的四大特性&#xff08;ACID&#xff09; 1. 原子性(atomicity)&#xff1a; 2. 一致性(consistency)&#xff1a; 3. 隔离性(isolation)&#xff1a; 4. 持久性(durability)&#xff1a; 二、死锁的产生及解决方法 三、事务的四种隔离级别 0 .封锁协议 …