时间:2021-05-20
最近在用Unity实现无人机的模拟飞行,但发现站里基本没有完整介绍如何实现该功能的博客,因时间紧迫,就自己简单做了一个仿真(不是完全按照现实物理情景来做,即通过各个螺旋桨旋转产生力带动机体飞行)。下面我会简述完全按现实物理情景实现模拟飞行,并详细描述我自己做的模拟飞行(不完全仿真),给各位提供参考。
因为我没有实现1:1仿真,所以这里只介绍思路,希望能给到读者一点启发。
背景:上面的现实模拟最麻烦之处在于要对四个螺旋桨(电机)实现控制并达到平衡,太麻烦了,调试要很久,网上又没有现成的代码(至少免费的我没有发现)。所以我自己简化了一下模型,并实现所需功能。
思路:简化模型的区别在于我不用四个螺旋桨(电机)来各自产生升力,形成合力来带动机体。而是直接将力加在机身上,即跳过了前面那一步,直接用合力来实现无人机的飞行。
实现步骤:以下为实现步骤,考虑到网上好像没有相关的博客和视频教程,我会尽量详细来叙述,所以会有点多。
1.导入一个无人机模型,并给整体设置Rigidbody和BoxCollider(注意最好Collider设成和模型差不多大)。
2. 写脚本1(Plane_Text)(总共需要写两个脚本,记为脚本1和脚本2),脚本1使其产生力带动机体运动
using System.Collections;using System.Collections.Generic;using System.IO.Pipes;using System.Runtime.CompilerServices;using System.Security.Cryptography.X509Certificates;using UnityEngine;using UnityEngine.UI;public class Plane_Text : MonoBehaviour{ private Rigidbody m_Rigidbody; public float speed = 5; public float angle = 0; private float x, y, z; public Transform target; void Start() { m_Rigidbody = gameObject.GetComponent<Rigidbody>();//获取组件 } void Update() { var vec = new Vector3(x, y, z); m_Rigidbody.AddForce(vec * speed, ForceMode.Force);//无人机朝vec向量方向运动,至于vec的取值由下面各个按键确定 /*******无人机飞机控制*********/ /*******W加油门(上升);S减油门(下降);A左转;D右转*********/ if (Input.GetKeyUp(KeyCode.W)) speed++; if (Input.GetKeyDown(KeyCode.W)) x = 0;y = 1;z = 0; if (Input.GetKeyUp(KeyCode.S)) speed--; if (Input.GetKeyDown(KeyCode.D)) angle++; this.transform.Rotate(Vector3.up * angle);//按下D键则一直右转,下同 if (Input.GetKeyUp(KeyCode.D)) angle = 0; this.transform.Rotate(Vector3.up * angle);//松开D键停止右转,下同 if (Input.GetKeyDown(KeyCode.A)) angle--; this.transform.Rotate(Vector3.up * angle); if (Input.GetKeyUp(KeyCode.A)) angle = 0; this.transform.Rotate(Vector3.up * angle); /*******↑前倾;↓后倾;←左倾;→右倾*********/ if (Input.GetKeyDown(KeyCode.LeftArrow))//按下←键朝向量(-1,2,0)方向运动,即左倾,但该左倾只是运动轨迹上左倾,模型是不会往左倾的,所以需要下脚本2里设置 x = -1; y = 2; z = 0; //这个取值随你定,但x一定是负的且z一定是0,至于x和y的大小就看你想飞行轨迹左倾多少来决定了 if (Input.GetKeyUp(KeyCode.LeftArrow))//当松开←键时,不再左倾,而是按原来(0,1,0)方向,即y轴向上,继续移动 x = 0; y = 1; z = 0;//同样因为是y轴,x和z的值必须为0,y的值看你心情 /**************************************************/ if (Input.GetKeyDown(KeyCode.RightArrow))//按下→键 x = 1; y = 2; z = 0; //这些我就不再解释了,跟上面“←键”的是一样的,只是倾斜方向不一样而已 if (Input.GetKeyUp(KeyCode.RightArrow)) x = 0; y = 1; z = 0; /**************************************************/ if (Input.GetKeyDown(KeyCode.UpArrow))//按下↑键 x = 0;y = 2;z = 1; if (Input.GetKeyUp(KeyCode.UpArrow)) x = 0; y = 1; z = 0; /**************************************************/ if (Input.GetKeyDown(KeyCode.DownArrow))//按下↓键 x = 0;y = 2;z = -1; if (Input.GetKeyUp(KeyCode.DownArrow)) x = 0; y = 1; z = 0; /**************************************************/ }}3.写脚本2(Plane_Move):该脚本是用来实现模型的前后左右倾的
using System.Collections;using System.Collections.Generic;using System.IO.Pipes;using System.Runtime.CompilerServices;using System.Security.Cryptography.X509Certificates;using UnityEngine;using UnityEngine.UI;public class Plane_Move : MonoBehaviour{ private Rigidbody m_Rigidbody; void Start() { m_Rigidbody = gameObject.GetComponent<Rigidbody>();//获取组件 } void Update() { /*******↑前倾;↓后倾;←左倾;→右倾*********/ if (Input.GetKeyDown(KeyCode.LeftArrow)) transform.rotation = Quaternion.Euler(0, 0, 10);//绕z轴转10°,即左倾,不一定是10,看你想倾多少就倾多少,别太大就行,下同 if (Input.GetKeyUp(KeyCode.LeftArrow)) transform.rotation = Quaternion.Euler(0, 0, 0);//松开按键恢复竖直向上飞,下同 /**************************************************/ if (Input.GetKeyDown(KeyCode.RightArrow)) this.transform.rotation = Quaternion.Euler(0, 0, -10); if (Input.GetKeyUp(KeyCode.RightArrow)) this.transform.rotation = Quaternion.Euler(0, 0, 0); /**************************************************/ if (Input.GetKeyDown(KeyCode.UpArrow)) this.transform.rotation = Quaternion.Euler(10, 0, 0); if (Input.GetKeyUp(KeyCode.UpArrow)) this.transform.rotation = Quaternion.Euler(0, 0, 0); /**************************************************/ if (Input.GetKeyDown(KeyCode.DownArrow)) this.transform.rotation = Quaternion.Euler(-10, 0, 0); if (Input.GetKeyUp(KeyCode.DownArrow)) this.transform.rotation = Quaternion.Euler(0, 0, 0); /**************************************************/ }}4.完成上面3步,我们就会得到两个脚本
5.然后就是把这两个脚本拖到无人机上(注意两个都要拖!),接着就是运行了(如果是运行不了肯定是你复制了我的代码,但脚本名又和我不一样的缘故)
6.最后运行成功(原谅我不会截动图给你们看运行结果)
7.当然有人会说螺旋桨怎么不会转啊,这也简单;首先给四个螺旋桨的顶点各建一个空物体(每个螺旋桨要绕着它对应的空物体旋转),然后再写一个脚本(Power_all),我这里就不区分正反桨了。(你要区分也行,就是把Vector3.down改成Vector3.up就是另一对桨)
using System.Collections.Generic;using System.Collections;using System.Globalization;using UnityEngine;using System;using UnityEngine.UI;//using UnityEngine.Debug;public class Power_all : MonoBehaviour{ public GameObject target01;//声明顶点 private float n = 10; // Update is called once per frame void Update() { this.transform.RotateAround(target01.transform.position, Vector3.down, 100f * n * Time.deltaTime);//该函数通过放入一个顶点,以及围绕这个顶点要旋转的x轴并给定旋转速度 //Vector3向量,在三维坐标系中带有方向和大小的数据,Vector3.up=(0,1,0)、Vector3.down=(0,-1,0)、Vector3.left=(-1,0,0)、Vector3.right=(1,0,0) }}8.将上面这个螺旋桨的脚本分别拖到各个桨叶模型上,然后将各个空物体拉到各个声明的顶点处即可。
9.上述即完成了简化的多旋翼无人机模拟飞行。可能有人会说我第2、3点谁规定了只能前倾一个角度,其实我是这样理解的,如果按照现实情景来完全模拟,确实前倾任意角度,甚至是180°,但前倾角度过大导致的结果是坠机,所以我设置在10°可以理解为安全倾角,当然你也可以自己该代码来实现自己想要的功能,我这里只是提供一个参考。
以上就是Unity使用物理引擎实现多旋翼无人机的模拟飞行的详细内容,更多关于Unity实现无人机飞行的资料请关注其它相关文章!
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
多旋翼无人机结构组成: 1、机架:机架是指多旋翼飞行器的机身架,是整个飞行系统的飞行载体。一般使用高强度重量轻的材料,例如碳纤维、PA66+30GF等材料。
小米无人机和大疆对比区别是: 1、飞行器的状态。客机、多旋翼飞行器等很多载人不载人的飞行器要想稳定飞行,首先最基础的问题是确定自己在空间中的位置和相关的状态。
京东集团在世界经济论坛年会现场宣布,京东物流无人机成功实现在印尼首次飞行,这也是中国物流无人机在海外的首次成功飞行。据了解,此次在印尼完成首飞的京东无人机目前已
1月22日消息,亿邦动力获悉,京东集团在世界经济论坛年会现场宣布,京东物流无人机成功实现在印尼首次飞行。京东方面表示,这也是中国物流无人机在海外的首次成功飞行。
此外,还有无人车已经进行上路测试;无人机截至昨天已经超过了17万个小时的测试,最新飞行的无人机可以飞到240公里;过完春节以后,京东第一架重型无人机将会进行实际