- [x] 新的訓練場地 - [x] 鬼的行動(移動和抓到目標後的處理) - [x] 物體位置重置 - [x] 搞懂ray perception sensor 3d 怎麼寫進去程式碼裡 - [x] 開始寫觀察 - [x] 開始寫利益 - [x] 開始訓練 8/28目標 鬼的移動,訓練場地(目標會重置),Target重生於4個點(+-8,0.5,+-8),鬼重生(0,0.5,0) ==>鬼抓到目標整體重置 搞懂ray perception sensor 3d的用法 ==>書寫觀察 8/29目標 開始寫利益 訓練和調整 8/30 訓練好的模型放進大地圖 觀察和修改 ![](https://hackmd.io/_uploads/ryw09wh63.png) Ray Perception Sensor https://www.cnblogs.com/gentlesunshine/p/12790103.html https://forum.unity.com/threads/how-to-create-these-perception-rays.816789/ https://juejin.cn/post/7111119260553838629 https://www.immersivelimit.com/tutorials/unity-ml-agents-penguins https://www.oreilly.com/library/view/practical-simulations-for/9781492089919/ch04.html 目前問題: RAY有碰到Target但沒有往他走。 1.可能是訓練的次數不夠 2.射線的目標沒有讀取(因為訓練不夠還不知道Target這個物體對他有好處) 需要加上對靠近牆壁的負利益 外圍不放入Wall的Tag裡,射線長度可以拉長,當足夠靠近牆壁給予不好的評分 一次訓練追目標和避開牆壁 分開訓練,先追目標(得到座標位置),在用前面的模型去訓練避開牆壁 先測試射線有沒有用處(拿走座標) 碰到的得分應該寫外面,推測(SetReward(-1f / MaxStep);可能會執行不到) https://forum.unity.com/threads/how-to-check-ray-perception-sensor-3d.1420445/ ``` private void checkRayCast() { RayPerceptionSensorComponent3D m_rayPerceptionSensorComponent3D = GetComponent<RayPerceptionSensorComponent3D>(); var rayOutputs = RayPerceptionSensor.Perceive(m_rayPerceptionSensorComponent3D.GetRayPerceptionInput()).RayOutputs; int lengthOfRayOutputs = rayOutputs.Length; // Alternating Ray Order: it gives an order of // (0, -delta, delta, -2delta, 2delta, ..., -ndelta, ndelta) // index 0 indicates the center of raycasts for (int i = 0; i < lengthOfRayOutputs; i++) { GameObject goHit = rayOutputs[i].HitGameObject; if (goHit != null) { var rayDirection = rayOutputs[i].EndPositionWorld - rayOutputs[i].StartPositionWorld; var scaledRayLength = rayDirection.magnitude; float rayHitDistance = rayOutputs[i].HitFraction * scaledRayLength; // Print info: string dispStr = ""; dispStr = dispStr + "__RayPerceptionSensor - HitInfo__:\r\n"; dispStr = dispStr + "GameObject name: " + goHit.name + "\r\n"; dispStr = dispStr + "Hit distance of Ray: " + rayHitDistance + "\r\n"; dispStr = dispStr + "GameObject tag: " + goHit.tag + "\r\n"; Debug.Log(dispStr); } } } ``` https://forum.unity.com/threads/problem-on-collectobservations-of-agents-for-learning-to-form-the-formation-of-uavs.1449667/#post-9085933 https://forum.unity.com/threads/how-to-check-ray-perception-sensor-3d.1420445/#post-8940981 https://forum.unity.com/threads/ray-perception-sensor-3d-vs-raycast.1456792/ https://docs.unity3d.com/Packages/com.unity.ml-agents@1.0/api/Unity.MLAgents.Sensors.RayPerceptionSensorComponent3D.html 座標和Ray Perception Sensor 3D 可以同時存在(問題點是CollectObservations裡面就會需要寫Ray Perception Sensor 的射線資訊 chat給的 ``` public override void CollectObservations(VectorSensor sensor) { // 使用 Ray Perception Sensor 3D 感知物體 RayPerceptionSensorComponent3D raySensor = GetComponent<RayPerceptionSensorComponent3D>(); float[] rayAngles = raySensor.GetRayAngles(); float[] rayDistances; string[] detectableObjects = raySensor.GetDetectableObjects(); // 觀察每個射線的距離 rayDistances = raySensor.Perceive(raySensor.MaxRayDegrees, rayAngles, detectableObjects, 0f, 0f); // 將距離觀察添加到 VectorSensor foreach (float distance in rayDistances) { sensor.AddObservation(distance); } // 也可以添加其他觀察,例如座標、速度等 sensor.AddObservation(target.localPosition); sensor.AddObservation(transform.localPosition); sensor.AddObservation(AgentRb.velocity); } ``` 結合別人的checkray ``` public override void CollectObservations(VectorSensor sensor) { // 使用 Ray Perception Sensor 3D 感知物體 RayPerceptionSensorComponent3D raySensor = GetComponent<RayPerceptionSensorComponent3D>(); RayPerceptionInput input = raySensor.GetRayPerceptionInput(); // 調用 checkRayCast 函數來處理射線感知的結果 checkRayCast(input); //座標 sensor.AddObservation(target.localPosition); sensor.AddObservation(transform.localPosition); sensor.AddObservation(AgentRb.velocity); } private void checkRayCast(RayPerceptionInput input) { RayPerceptionOutput rayOutput = RayPerceptionSensor.Perceive(input); int lengthOfRayOutputs = rayOutput.RayOutputs.Length; // 處理射線感知結果 for (int i = 0; i < lengthOfRayOutputs; i++) { GameObject goHit = rayOutput.RayOutputs[i].HitGameObject; if (goHit != null) { var rayDirection = rayOutput.RayOutputs[i].EndPositionWorld - rayOutput.RayOutputs[i].StartPositionWorld; var scaledRayLength = rayDirection.magnitude; float rayHitDistance = rayOutput.RayOutputs[i].HitFraction * scaledRayLength; // 打印信息或者进行其他处理 string dispStr = ""; dispStr = dispStr + "__RayPerceptionSensor - HitInfo__:\r\n"; dispStr = dispStr + "GameObject name: " + goHit.name + "\r\n"; dispStr = dispStr + "Hit distance of Ray: " + rayHitDistance + "\r\n"; dispStr = dispStr + "GameObject tag: " + goHit.tag + "\r\n"; Debug.Log(dispStr); } } } ``` ![](https://hackmd.io/_uploads/r1ljnI5u03.png) Agent 射線 1.碰到牆壁(Wall) 2.碰到目標(Target) 3.沒碰到東西 依距離給予利益 1?->1距離要多少給負的利益,距離要分幾次(例如: 太近給高的負利益,遠一點給低的負利益) 2?->2正的利益要給多少才會最好,讓Agent不會因為目標太靠近牆壁並因為牆壁的利益而不往目標走 3?->3要不要給利益 (先用座標訓練抓位子,後面加上RAY去訓練避開牆壁) ==訓練重點 == 地圖大小會影響訓練的成效,地圖變大次數就需要增加許多,次數若沒變利益會很低 ![](https://hackmd.io/_uploads/HkH7EF0ya.png) 觀察需要多一個Agent往Target的特徵,該特徵表示Agent到目標的方向向量。可以計算目標相對於Agent的相對位置,然後將該向量歸一化,以表示方向。 每次Agent觀察時,計算目標的相對方向向量,並將其添加到觀察中。這樣,Agent就能夠知道目標相對於自己的位置,包括目標是否在移動。 根據目標的方向向量,Agent可以調整其行為,例如朝向目標的方向移動,以追趕目標。 射線調整,距離牆壁的長度要調整 {%youtube 97ElaUAlflI %} ![](https://hackmd.io/_uploads/BklXtPhe6.png)