Unity开发数字化看板-通用的设备运动同步

news2024/11/18 7:48:01

通用的设备运动同步

通过获取实时采集运动位置,发送到unity程序中,通过比例运算,转换成模型的运动位置,实现虚实同步。

在工业设备中,复杂的运动进行分析、分解,最本质的的运动就是平移和转动,在空间上就是3个维度的平移和旋转,包括:x轴平移,y轴平移,z轴平移,x轴旋转,Y轴旋转,Z轴旋转。

当然根据接收的数据不同,可能有的是一维运动,有的是多个维度合并一起运动。

实现实控虚的主要几个点:

  1. 初始化位置映射,实际设备确定一个零点,在模型需要找到对应零点,记录当前位置
  2. 比例换算,模型显示跟实际尺寸存在非完全一致或者单位换算的问题,对部件进行平移需要换算,旋转角度则不需要
  3. 旋转中心点调整

实现运动控制脚本:

主要实现一个运动控制基类MoveBase和3个维度平移和旋转控制(6个脚本)

基类MoveBase实现

首先实现初始化

InitPosition变量用于存储当前部件模型的初始化位置,虚函数InitLocation()用于根据InitPosition值和不同类型的运动进行不同初始化,具体初始化内容在子类中实现。


    /// <summary>
    /// 初始化位置
    /// </summary>
    public float InitPosition;
    
    /// <summary>
    /// 初始化位置参数
    /// </summary>
    public virtual void InitLocation()
    {

    }

比例换算:

在平移中:

(模型位置 − 模型初始位置) 模型可运动长度 = 实际位置 实际可运动长度 \frac{(模型位置-模型初始位置)}{模型可运动长度}=\frac{实际位置}{实际可运动长度} 模型可运动长度(模型位置模型初始位置)=实际可运动长度实际位置

在旋转:

模型当前角度 = 模型偏转零点 + 转动角度 模型当前角度=模型偏转零点+转动角度 模型当前角度=模型偏转零点+转动角度

设置了四个参数,DataPosition是传过来的位置,就是实际位置;NowPosition是当前位置,就是模型当前位置;MoveLength是模型可运动长度;ActualLength是实际可运动长度;MoveLengthActualLength只有在平移运动式有效,如果是旋转则默认设置为0,不处理。

    /// <summary>
    /// 传过来的位置
    /// </summary>
    protected float DataPosition;
    /// <summary>
    /// 当前位置
    /// </summary>
    public float NowPosition;
    /// <summary>
    /// 模型可移动长度,比例计算
    /// </summary>
    public float MoveLength = 1;
    /// <summary>
    /// 实际可移动长度
    /// </summary>
    public float ActualLength = 1;

运算公式:

模型实时位置 = 模型初始化位置 + 实际位置 ∗ 模型可移动长度 实际可移动长度 模型实时位置=模型初始化位置+\frac{实际位置*模型可移动长度}{实际可移动长度} 模型实时位置=模型初始化位置+实际可移动长度实际位置模型可移动长度

在脚本FixedUpdate()中实时更新模型位置,先使用公式计算当前模型位置,然后调用UpdateModelPosition()更新位置,具体更新在对应子类中转换为坐标更新或者角度旋转。

    private void FixedUpdate()
    {

        if (IsChange())
        {
            NowPosition = InitPosition + DataPosition * MoveLength / ActualLength;
            UpdateModelPosition();
        }

    }
    /// <summary>
    /// 更新位置
    /// </summary>
    public virtual void UpdateModelPosition()
    {

    }

MoveBase基类完整脚本:

/// <summary>
/// 运动控制基类(平移、旋转)
/// </summary>
public class MoveBase : MonoBehaviour
{
    /// <summary>
    /// 运动控制对象
    /// </summary>
    public Transform MoveObject;

    /// <summary>
    /// 传过来的位置
    /// </summary>
    protected float DataPosition;

    /// <summary>
    /// 初始化位置
    /// </summary>
    public float InitPosition;
    /// <summary>
    /// 当前位置
    /// </summary>
    public float NowPosition;

    /// <summary>
    /// 模型移动长度,比例计算
    /// </summary>
    public float MoveLength = 1;
    /// <summary>
    /// 实际移动长度
    /// </summary>
    public float ActualLength = 1;

    /// <summary>
    /// 设置实时数据
    /// </summary>
    /// <param name="pos"></param>
    public virtual void SetDataPos(float pos)
    {
        DataPosition = pos;
    }

    public bool IsChange()
    {

        if (NowPosition != DataPosition)
        {
            return true;
        }
        else
        {
            return false;
        }
    }


    void Start()
    {
        MoveObject = gameObject.transform;
    }
    /// <summary>
    /// 初始化位置参数
    /// </summary>
    public virtual void InitLocation()
    {

    }

    private void FixedUpdate()
    {
        if (IsChange())
        {
            NowPosition = InitPosition + DataPosition * MoveLength / ActualLength;
            UpdateModelPosition();
        }
    }
    /// <summary>
    /// 更新位置
    /// </summary>
    public virtual void UpdateModelPosition()
    {

    }
}


各个维度控制脚本:

X轴平移:

public class XMove : MoveBase
{
    public override void InitLocation()
    {
        MoveObject.localPosition = new Vector3(InitPosition, MoveObject.localPosition.y, MoveObject.localPosition.z);
    }

    public override void UpdateModelPosition()
    {
            MoveObject.localPosition = new Vector3(NowPosition, MoveObject.localPosition.y, MoveObject.localPosition.z);
    }
}

Y轴平移:

public class YMove : MoveBase
{
    public override void InitLocation()
    {
        MoveObject.localPosition = new Vector3(MoveObject.localPosition.x, InitPosition, MoveObject.localPosition.z);
    }

    public override void UpdateModelPosition()
    {
        MoveObject.localPosition = new Vector3(MoveObject.localPosition.x, NowPosition, MoveObject.localPosition.z);

    }
}

Z轴平移:

public class ZMove : MoveBase
{
    public override void InitLocation()
    {
        MoveObject.localPosition = new Vector3(MoveObject.localPosition.x, MoveObject.localPosition.y, InitPosition);
    }

    public override void UpdateModelPosition()
    {
        MoveObject.localPosition = new Vector3(MoveObject.localPosition.x, MoveObject.localPosition.y, NowPosition);
    }
}

X轴旋转:

public class XRotate : MoveBase
{
    public override void InitLocation()
    {
        MoveObject.localRotation = Quaternion.Euler(InitPosition, MoveObject.localPosition.y, MoveObject.localPosition.z);
    }

    public override void UpdateModelPosition()
    {
        MoveObject.localRotation = Quaternion.Euler(NowPosition, MoveObject.localPosition.y, MoveObject.localPosition.z);
    }
}

Y轴旋转:

public class YRotate : MoveBase
{
    public override void InitLocation()
    {
        MoveObject.localRotation = Quaternion.Euler(MoveObject.localPosition.x, InitPosition, MoveObject.localPosition.z);
    }
    public override void UpdateModelPosition()
    {
        MoveObject.localRotation = Quaternion.Euler(MoveObject.localPosition.x, NowPosition, MoveObject.localPosition.z);
    }
}

Z轴旋转:

public class ZRotate : MoveBase
{
    public override void InitLocation()
    {
        MoveObject.localRotation = Quaternion.Euler(MoveObject.localPosition.x, MoveObject.localPosition.y, InitPosition);
    }
    public override void UpdateModelPosition()
    {
        MoveObject.localRotation = Quaternion.Euler(MoveObject.localPosition.x, MoveObject.localPosition.y, NowPosition);
    }
}

测试:

创建两个Cube物体用于测试

在这里插入图片描述

在MoveCube上面挂上Zmove脚本,并且修改脚本参数用于模拟运动

在这里插入图片描述

写一个测试的控制脚本,将他挂在随便一个物体上(相机或者Cube),将MoveCube物体复制给Move参数,然后运行,就可以看到物体运动。

在这里插入图片描述

public class MoveTest : MonoBehaviour
{
    public MoveBase Move;
    int pos = 0;
    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {

    }
    private void FixedUpdate()
    {
        pos++;
        Move.SetDataPos(pos);
    }
}

效果:

在这里插入图片描述

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

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

相关文章

美团到店暑期实习Java一面

目录1.rabbitmq如何避免消息丢失 &#xff08;三个阶段&#xff09;2.如何保证消息的顺序性3.如何保证消息不被重复消费4.缓存与数据库的不一致性5.redis的过期策略和内存淘汰策略6.简单说下LRU的实现7.用原生redis实现分布式锁&#xff0c;锁误删的情况8.锁续期如何去考量9.缓…

MySQL-----库的操作

文章目录前言一、创建数据库二、创建数据库实例三、字符集和校验规则1.查看系统默认字符集以及校验规则.2.查看数据库支持的字符集3.查看数据库支持的字符集校验规则4.校验规则对数据库的影响四、操纵数据库1.查看数据库2.显示创建语句4.修改数据库5.删除数据库6.备份和恢复6.1…

Diffusion模型系列文章

DDPM 论文 扩散模型包括两个过程&#xff1a;前向过程&#xff08;forward process&#xff09;和反向过程&#xff08;reverse process&#xff09;&#xff0c;其中前向过程又称为扩散过程&#xff08;diffusion process&#xff09;&#xff0c;如下图所示&#xff0c;从x…

【音视频第8天】mediasoup拥塞控制【未完待续】

WebRTC的拥塞控制方式主要有以下几个&#xff1a;Transport-cc、BBR-congestion、remb&#xff08;BBR已被google从webrtc移除了&#xff09;。mediasoup支持Transport-cc和remb。 一、前言 实时通信的延时指标 视频服务质量指标 音视频服务质量与带宽之间的矛盾、实时性与服…

【微信小程序】初识微信小程序组件

作者简介&#xff1a;一名C站萌新&#xff0c;前来进行小程序的前进之路博主主页&#xff1a;大熊李子&#x1f43b; 一、组件的创建与引用 1.1 创建组件 在项目的根目录中&#xff0c;鼠标右键&#xff0c;创建 components -> test 文件夹在新建的 components -> test…

NLP / LLMs中的Temperature 是什么?

ChatGPT, GPT-3, GPT-3.5, GPT-4, LLaMA, Bard等大型语言模型的一个重要的超参数 大型语言模型能够根据给定的上下文或提示生成新文本&#xff0c;由于神经网络等深度学习技术的进步&#xff0c;这些模型越来越受欢迎。可用于控制生成语言模型行为的关键参数之一是Temperature …

[译]自下而上认识Elasticsearch

注意:原文发表时间是13年,所以实现有可能与新版不一致. 原文地址:https://www.elastic.co/cn/blog/found-elasticsearch-from-the-bottom-up Introduction 在本系列文章中,我们从一个新的视角来看ElasticSearch.我们将从下往上,从抽象的底层实现到用户可见层,我们在向上移动的…

【JaveEE】网络编程之TCP套接字、UDP套接字

目录 1.网络编程的基本概念 1.1为什么需要网络编程 1.2服务端与用户端 1.3网络编程五元组 1.4套接字的概念 2.UDP套接字编程 2.1UDP套接字的特点 2.2UDP套接字API 2.2.1DatagramSocket类 2.2.2DatagramPacket类 2.2.3基于UDP的回显程序 2.2.4基于UDP的单词查询 …

免疫力低会怎么样 什么情况会导致免疫降低

都说免疫力是很重要的&#xff0c;它会我们健康的第一道防线&#xff0c;但是当免疫力降低的时候&#xff0c;会出现哪些情况&#xff1f;为什么免疫力会降低&#xff1f; 免疫力是人体的防御系统&#xff0c;就像是维持人体正常运转的军队。免疫力的高低&#xff0c;一定程度上…

再探pytorch的Dataset和DataLoader

本文参加新星计划人工智能(Pytorch)赛道&#xff1a;https://bbs.csdn.net/topics/613989052本文从分类、检测、分割三大任务的角度来剖析pytorch得dataset和dataloader源码&#xff0c;可以让初学者深刻理解每个参数的由来和使用&#xff0c;并轻松自定义dataset。思考&#x…

SQL LIMIT

SQL LIMIT SQL LIMIT子句简介 要检索查询返回的行的一部分&#xff0c;请使用LIMIT和OFFSET子句。 以下说明了这些子句的语法&#xff1a; SELECT column_list FROMtable1 ORDER BY column_list LIMIT row_count OFFSET offset;在这个语法中&#xff0c; row_count确定将返…

Html5版贪吃蛇游戏制作(经典玩法)

回味经典小游戏&#xff0c;用Html5做了个贪吃蛇的小游戏&#xff0c;完成了核心经典玩法的功能。 游戏可以通过电脑的键盘“方向键”控制&#xff0c;也可以点击屏幕中的按钮进行控制。&#xff08;支持移动端哈&#xff09; 点击这里试玩 蛇的移动是在18 x 18的格子中进行移…

sqoop数据导入

创建数据库 mysql全表数据导入hdfs mysql查询数据导入hdfs mysql指定列导入hdfs 使用查询条件关键字将mysql数据导入hdfs mysql数据导入hive 创建数据库 hive中创建user表 create table users( id bigint, name string ) row format delimited fields terminated by &…

数据结构 - 归并排序 | C

思路分析 什么是归并&#xff1f; 示例&#xff1a;&#xff08;归并后的结果copy到原数组&#xff09; 逻辑&#xff1a; if (a[begin1] < a[begin2]) {tmp[i] a[begin1];} else {tmp[i] a[begin2];} 归并排序 分解到“有序”再归并 递归 int middle (left righ…

哈希——unordered系列关联式容器

目录 unordered系列关联式容器 概念 unordered_map 无序去重 operator[] unordered_set 无序去重 OJ练习题 重复n次的元素 两个数组的交集 两个数的交集二 底层结构 概念 哈希冲突 闭散列 结点的定义 扩容 字符串取模 插入 查找 删除 闭散列完整代码 开…

安卓远程控制软件哪个好用

如果您曾希望将个人电脑放在口袋里&#xff0c;那么您可能只需要安卓远程访问软件。 没有远程访问应用程序&#xff1a;使用和控制计算机的唯一方法是坐在计算机前并手动输入命令。 使用远程访问应用程序&#xff1a;您可以在世界任何地方通过 Internet 连接从您的安卓平板电…

【30天python从零到一】---第七天:列表和元组

&#x1f34e; 博客主页&#xff1a;&#x1f319;披星戴月的贾维斯 &#x1f34e; 欢迎关注&#xff1a;&#x1f44d;点赞&#x1f343;收藏&#x1f525;留言 &#x1f347;系列专栏&#xff1a;&#x1f319; Python专栏 &#x1f319;请不要相信胜利就像山坡上的蒲公英一样…

计算机组成原理---第五章中央处理器

&#xff08;一&#xff09;CPU 的功能和组成 CPU 的功能 Ⅰ 概述&#xff1a;当程序指令装入内存储器后&#xff0c;CPU 用来自动完成取指令和执行指令的任务。 Ⅱ CPU 的功能&#xff1a;①指令控制 ②操作控制 ③时间控制 ④数据加工 2.CPU 的基本组成 CPU 的基本部分为运…

【论文阅读】[JBHI] VLTENet、[ISBI]

[JBHI] VLTENet 论文连接&#xff1a;VLTENet: A Deep-Learning-Based Vertebra Localization and Tilt Estimation Network for Automatic Cobb Angle Estimation | IEEE Journals & Magazine | IEEE Xplore Published in: IEEE Journal of Biomedical and Health Infor…

9.1 相关分析

学习目标&#xff1a; 如果我要学习相关分析&#xff0c;我可能会按照以下步骤进行&#xff1a; 确定学习相关分析的目的和应用场景&#xff0c;例如研究两个变量之间的相关性、了解变量之间的关系、预测未来趋势等。学习相关分析的基本概念和原理&#xff0c;包括相关系数、…