- [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
訓練好的模型放進大地圖
觀察和修改

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);
}
}
}
```

Agent 射線 1.碰到牆壁(Wall) 2.碰到目標(Target) 3.沒碰到東西
依距離給予利益
1?->1距離要多少給負的利益,距離要分幾次(例如: 太近給高的負利益,遠一點給低的負利益)
2?->2正的利益要給多少才會最好,讓Agent不會因為目標太靠近牆壁並因為牆壁的利益而不往目標走
3?->3要不要給利益
(先用座標訓練抓位子,後面加上RAY去訓練避開牆壁)
==訓練重點
==
地圖大小會影響訓練的成效,地圖變大次數就需要增加許多,次數若沒變利益會很低

觀察需要多一個Agent往Target的特徵,該特徵表示Agent到目標的方向向量。可以計算目標相對於Agent的相對位置,然後將該向量歸一化,以表示方向。
每次Agent觀察時,計算目標的相對方向向量,並將其添加到觀察中。這樣,Agent就能夠知道目標相對於自己的位置,包括目標是否在移動。
根據目標的方向向量,Agent可以調整其行為,例如朝向目標的方向移動,以追趕目標。
射線調整,距離牆壁的長度要調整
{%youtube 97ElaUAlflI %}
