Skip to content

Commit

Permalink
【MA基礎開発】TelloSDKの仕様に合わせてドローン制御方式を変更。バッテリー概念の追加。偵察ドローンエージェントスクリプトを追加. #1
Browse files Browse the repository at this point in the history
  • Loading branch information
tsyu12345 committed Feb 17, 2024
1 parent 2ba6107 commit 5001a8b
Show file tree
Hide file tree
Showing 15 changed files with 1,176 additions and 135 deletions.
117 changes: 117 additions & 0 deletions MAEasySimulator/Assets/BoxReady.prefab
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &1464484887366625871
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2240881192534159605}
m_Layer: 0
m_Name: BoxReady
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &2240881192534159605
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1464484887366625871}
m_LocalRotation: {x: 0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 1686881325863600557}
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &7628867827952849558
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1686881325863600557}
- component: {fileID: 4593160332070172903}
- component: {fileID: 1052598617310108787}
m_Layer: 0
m_Name: default
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &1686881325863600557
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7628867827952849558}
m_LocalRotation: {x: 0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: -0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 2240881192534159605}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!33 &4593160332070172903
MeshFilter:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7628867827952849558}
m_Mesh: {fileID: -2432090755550338912, guid: 108d7f9df3c40e24fa41d9378c7dc09b, type: 3}
--- !u!23 &1052598617310108787
MeshRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7628867827952849558}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_StaticShadowCaster: 0
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RayTraceProcedural: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 2100000, guid: ae084d9f2e473734d896276d52440441, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_AdditionalVertexStreams: {fileID: 0}
7 changes: 7 additions & 0 deletions MAEasySimulator/Assets/BoxReady.prefab.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion MAEasySimulator/Assets/Drone/Art/material/blue.mat
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ Material:
- _ZWrite: 1
m_Colors:
- _BaseColor: {r: 0, g: 0.638464, b: 1, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _Color: {r: 0, g: 0.638464, b: 1, a: 1}
- _EmissionColor: {r: 0.062032763, g: 0.55507654, b: 0.7735849, a: 1}
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
m_BuildTextureStacks: []
217 changes: 196 additions & 21 deletions MAEasySimulator/Assets/DroneController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,46 +5,126 @@
using Unity.MLAgents.Actuators;
using Unity.MLAgents.Sensors;

/// <summary>
/// ドローン共通コンポーネント
/// </summary>
public class DroneController : MonoBehaviour {

[Header("Movement Parameters")]
public float moveSpeed = 10f; // 移動速度
public float verticalForce = 10f; // 上昇・下降の強さ
public float tiltAng = 10f; // 傾きの角度
public float tiltVel = 5f; // 傾きの速度
public float rotSpeed = 100f; // 回転速度
public float sidewaysTiltAmount;
public float forwardTiltAmount;
public float rotAmount;
[Header("Battery")]
public float batteryLevel = 100f; // バッテリー残量の初期値
private float batteryDrainRate = 1f; // 1秒あたりのバッテリー消費率

[Header("Communication Parameters")]
public float communicationRange = 10f; // 通信範囲(半径)
public GameObject communicateArea; //通信電波域を表すオブジェクト円形(Droneの子要素として定義)

[Header("Crash Objects")]
public List<string> CrashTags; //衝突判定対象のタグ
public Rigidbody Rbody;

/**Events*/
public delegate void OnReceiveMessage(string message);
public OnReceiveMessage onReceiveMsg;
public delegate void OnCrash(Vector3 crashPos);
public OnCrash onCrash;
public delegate void OnEmptyButtery();
public OnEmptyButtery onEmptyBattery;
/***/
public List<string> CommunicateTargetTags;
private string Team;

void Start() {
Rbody = GetComponent<Rigidbody>();
communicateArea.transform.localScale = new Vector3(communicationRange, communicationRange, communicationRange);
StartCoroutine(BatteryDrainCoroutine());
}

void OnTriggerEnter(Collider other) {
if (CrashTags.Contains(other.tag)) {
onCrash?.Invoke(other.transform.position);
FreeFall();
}
}

public void RegisterTeam(string team) {
Team = team;
}
public void AddCommunicateTarget(string target) {
CommunicateTargetTags.Add(target);
}

public void InHeuristicCtrl(in ActionBuffers actionsOut) {
var action = actionsOut.ContinuousActions;
//WASD定義
if(Input.GetKey(KeyCode.W)) {
//前進
action[1] = 1f;
} else if (Input.GetKey(KeyCode.S)) {
//後退
action[1] = -1f;
}

if (Input.GetKey(KeyCode.A)) {
//左移動
action[0] = -1f;
} else if (Input.GetKey(KeyCode.D)) {
//右移動
action[0] = 1f;
}

if (Input.GetKey(KeyCode.LeftArrow)) {
//左回転
action[2] = -1f;
} else if (Input.GetKey(KeyCode.RightArrow)) {
//右回転
action[2] = 1f;
}

if (Input.GetKey(KeyCode.Space)) {
//上昇
action[3] = 1f;
} else if (Input.GetKey(KeyCode.LeftShift)) {
//下降
action[3] = -1f;
}
}

public void FlyingCtrl(ActionBuffers actions) {
float horInput = actions.ContinuousActions[0];
float verInput = actions.ContinuousActions[1];
float rotInput = actions.ContinuousActions[2];
float horInput = actions.ContinuousActions[0]; //水平方向の入力(左右)
float verInput = actions.ContinuousActions[1]; //垂直方向の入力(前後)
float rotInput = actions.ContinuousActions[2]; //回転方向の入力
float altInput = actions.ContinuousActions[3]; //高度方向の入力(上下)

if (batteryLevel <= 0) {
return;
}

// 水平、垂直方向の移動計算
Vector3 moveDirection = new Vector3(horInput, 0, verInput) * moveSpeed;
Rbody.AddForce(transform.TransformDirection(moveDirection));
if(horInput > 0) {
Right(horInput);
} else {
Left(Mathf.Abs(horInput));
}
if(verInput > 0) {
Forward(verInput);
} else {
Back(Mathf.Abs(verInput));
}
//回転
if(rotInput > 0) {
Cw(rotInput);
} else if (rotInput < 0) {
Ccw(Mathf.Abs(rotInput));
}
//高度方向の移動
if(altInput > 0) {
Up(altInput);
} else if (altInput < 0) {
Down(Mathf.Abs(altInput));
}

// 入力に基づいて傾き・回転を計算
sidewaysTiltAmount = Mathf.Lerp(sidewaysTiltAmount, -horInput * tiltAng, tiltVel * Time.fixedDeltaTime);
forwardTiltAmount = Mathf.Lerp(forwardTiltAmount, verInput * tiltAng, tiltVel * Time.fixedDeltaTime);
rotAmount += rotInput * rotSpeed * Time.fixedDeltaTime;

// 傾き・回転をドローンに適用
Quaternion targetRot = Quaternion.Euler(forwardTiltAmount, rotAmount, sidewaysTiltAmount);
transform.rotation = targetRot;
}

/// <summary>
Expand All @@ -54,7 +134,7 @@ public bool Communicate(string message) {
Collider[] hitColliders = Physics.OverlapSphere(transform.position, communicationRange); //範囲内にあるコライダーを取得
var result = false;
foreach (var hitCollider in hitColliders) {
if (hitCollider.tag == "Drone") { //TODO:ハードコードを避ける
if (CommunicateTargetTags.Contains(hitCollider.tag)) {
hitCollider.GetComponent<DroneController>().ReceiveMessage(message);
result = true;
}
Expand All @@ -67,6 +147,101 @@ public bool Communicate(string message) {
/// </summary>
public void ReceiveMessage(string message) {
Debug.Log("Message received: " + message);
onReceiveMsg?.Invoke(message);
}


private void FreeFall() {
Rbody.useGravity = true;
//FreezePosition,FreezeRotationを解除
Rbody.constraints = RigidbodyConstraints.None;
}

private IEnumerator BatteryDrainCoroutine() {
while (batteryLevel > 0) {
yield return new WaitForSeconds(1);
batteryLevel -= batteryDrainRate;
Debug.Log($"Battery Level: {batteryLevel}%");
}
onEmptyBattery?.Invoke();
FreeFall();
}

//NOTE:以下はTello SDKを参考
private static Vector3 RenewPosLerp(Vector3 currentPos, Vector3 targetPos, float speed) {
return Vector3.Lerp(currentPos, targetPos, speed * Time.deltaTime);
}
/// <summary>
/// 機体を上昇させる
/// </summary>
/// <param name="value">どのくらいの座標上昇させるか</param>
private void Up(float value) {
Vector3 newPos = new Vector3(transform.localPosition.x, transform.localPosition.y + value, transform.localPosition.z);
transform.localPosition = RenewPosLerp(transform.localPosition, newPos, moveSpeed);
}

/// <summary>
/// 機体を下降させる
/// </summary>
/// <param name="value">どのくらいの座標下降させるか</param>
private void Down(float value) {
Vector3 newPos = new Vector3(transform.localPosition.x, transform.localPosition.y - value, transform.localPosition.z);
transform.localPosition = RenewPosLerp(transform.localPosition, newPos, moveSpeed);
}

/// <summary>
/// Moves the aircraft forward based on its current orientation.
/// </summary>
/// <param name="value">How much to move the aircraft forward.</param>
private void Forward(float value) {
Vector3 newPos = transform.position + transform.forward * value;
transform.position = RenewPosLerp(transform.position, newPos, moveSpeed);
}

/// <summary>
/// Moves the aircraft backward based on its current orientation.
/// </summary>
/// <param name="value">How much to move the aircraft backward.</param>
private void Back(float value) {
Vector3 newPos = transform.position - transform.forward * value;
transform.position = RenewPosLerp(transform.position, newPos, moveSpeed);
}

/// <summary>
/// Moves the aircraft to the left based on its current orientation.
/// </summary>
/// <param name="value">How much to move the aircraft to the left.</param>
private void Left(float value) {
Vector3 newPos = transform.position - transform.right * value;
transform.position = RenewPosLerp(transform.position, newPos, moveSpeed);
}

/// <summary>
/// Moves the aircraft to the right based on its current orientation.
/// </summary>
/// <param name="value">How much to move the aircraft to the right.</param>
private void Right(float value) {
Vector3 newPos = transform.position + transform.right * value;
transform.position = RenewPosLerp(transform.position, newPos, moveSpeed);
}


/// <summary>
/// 時計回りに旋回
/// </summary>
/// <param name="value">How much to rotate the aircraft clockwise.</param>
private void Cw(float value) {
transform.Rotate(Vector3.up * rotSpeed * Time.deltaTime);
}

/// <summary>
/// 反時計回りに機体を回転させる
/// </summary>
/// <param name="value">How much to rotate the aircraft counterclockwise.</param>
private void Ccw(float value) {
transform.Rotate(Vector3.down * rotSpeed * Time.deltaTime);
}



}
Loading

0 comments on commit 5001a8b

Please sign in to comment.