前往
大廳
主題

狼 追逐 V1

夏洛爾 | 2022-12-10 02:22:20 | 巴幣 0 | 人氣 189


Wolf Run V1

實驗目標:
1.進入靜立狀態後,進入追逐狀態,在追逐狀態下,要能持續跑至接近目標的距離內
2.尺寸介於1-5倍

實驗設計:
1.任何弱點觸地皆失敗 (尾巴和四個小腿並非是弱點)
2.非弱點肢體
if(wolfBodies[i].damageCoef > 0f){clampReward += -0.01f * wolfBodies[i].damageCoef;}
3.
//Set: judge.endEpisode = false//Set: useClampReward = true//Set: SharpingBuffer Len=250 Th=-0.4if(weaknessOnGround){if(inferenceMode){brainMode = BrainMode.GetUp;SetModel("WolfGetUp", getUpBrain);behaviorParameters.BehaviorType = BehaviorType.InferenceOnly;}else{AddReward(-1f);judge.outLife++;judge.Reset();return;}}else if(wolfRoot.localPosition.y < -10f){if(inferenceMode){brainMode = BrainMode.GetUp;SetModel("WolfGetUp", getUpBrain);behaviorParameters.BehaviorType = BehaviorType.InferenceOnly;}else{AddReward(-1f);judge.outY++;judge.Reset();return;}}else{targetSmoothPosition = targetPositionBuffer.GetSmoothVal();headDir = targetSmoothPosition - stageBase.InverseTransformPoint(wolfHeadRb.position);rootDir = targetSmoothPosition - stageBase.InverseTransformPoint(wolfRootRb.position);flatTargetVelocity = rootDir;flatTargetVelocity.y = 0f;targetDistance = flatTargetVelocity.magnitude;Vector3 forwardDir = flatTargetVelocity.normalized;Vector3 flatLeftDir = Vector3.Cross(flatTargetVelocity, Vector3.up);lookAngle = Mathf.InverseLerp(180f, 0f, Vector3.Angle(wolfHead.right * -1f, headDir));//SideUpupAngle = Mathf.InverseLerp(180f, 0f, Vector3.Angle(wolfHead.forward, flatLeftDir));aimVelocity = flatTargetVelocity.normalized;aimVelocity.y = 0.2f;spineLookAngle = Mathf.InverseLerp(180f, 30f, Vector3.Angle(wolfSpine.right*-1f, forwardDir));//SideUpspineUpAngle = Mathf.InverseLerp(180f, 0f, Vector3.Angle(wolfSpine.forward, flatLeftDir));rootLookAngle = Mathf.InverseLerp(180f, 30f, Vector3.Angle(wolfRoot.forward, forwardDir));//SideUprootUpAngle = Mathf.InverseLerp(180f, 0f, Vector3.Angle(wolfRoot.right*-1f, flatLeftDir));leftThighAngle = Mathf.InverseLerp(180f, 0f, Vector3.Angle(wolfLeftThigh.forward * -1f, flatLeftDir));rightThighAngle = Mathf.InverseLerp(180f, 0f, Vector3.Angle(wolfRightThigh.forward * -1f, flatLeftDir));leftUpperArmAngle = Mathf.InverseLerp(180f, 0f, Vector3.Angle(wolfLeftUpperArm.forward * -1f, flatLeftDir));rightUpperArmAngle = Mathf.InverseLerp(180f, 0f, Vector3.Angle(wolfRightUpperArm.forward * -1f, flatLeftDir));tailAngle = Mathf.InverseLerp(180f, 0f, Vector3.Angle(wolfTail.right, flatTargetVelocity));avgVelocity = velocityBuffer.GetSmoothVal();velocityAngle = Vector3.Angle(avgVelocity, aimVelocity);velocityAngleCoef = Mathf.InverseLerp(180f, 0f, velocityAngle);flatVelocity = avgVelocity;flatVelocity.y = 0f;flatVelocityManitude = flatVelocity.magnitude;float sizeScale = Mathf.Lerp(1f, 2.5f, currentSize/5f);velocityCoef = Mathf.InverseLerp(0f, 15f*sizeScale, Vector3.Project(avgVelocity, aimVelocity).magnitude );flatVelocityAngle = Vector3.Angle(flatVelocity, flatTargetVelocity);if(!inferenceMode){if(targetDistance > nearModeRange){if(Time.fixedTime - landingMoment > landingBufferTime){bool outSpeed = flatVelocityManitude < Mathf.Lerp(0f, 7f*sizeScale, (Time.fixedTime - landingMoment - landingBufferTime)/4f);bool outDirection = flatVelocityAngle > Mathf.Lerp(180f, 10f, (Time.fixedTime - landingMoment - landingBufferTime)/4f);float motionLimit = Mathf.Lerp(0f, 0.7f, (Time.fixedTime - landingMoment - landingBufferTime)/4f);float motionLimit2 = Mathf.Lerp(0f, 0.8f, (Time.fixedTime - landingMoment - landingBufferTime)/4f);float sharpingResetVal = Mathf.Lerp(0f, sharpingResetThreshould, (Time.fixedTime - landingMoment - landingBufferTime - 3f)/5f);bool outMotion = lookAngle < motionLimit2 || upAngle < motionLimit2 || leftThighAngle < motionLimit2 || rightThighAngle < motionLimit2 || spineUpAngle < motionLimit || rootUpAngle < motionLimit || leftUpperArmAngle < motionLimit2 || rightUpperArmAngle < motionLimit2;if( outSpeed || outDirection || outMotion){// AddReward(-1f);if(outSpeed){#if UNITY_EDITORDebug.Log("outSpeed");#endifclampReward += -0.05f;judge.outSpeed++;}if(outDirection){#if UNITY_EDITORDebug.Log("outDirection");#endifclampReward += -0.05f;judge.outDirection++;}if(outMotion){#if UNITY_EDITORDebug.Log("outMotion");#endifclampReward += -0.035f;judge.outMotion++;}sharpingBuffer.PushVal(-1f);// judge.Reset();// return;}else{sharpingBuffer.PushVal(0f);}#if UNITY_EDITORsharpingVal = sharpingBuffer.GetSmoothVal();#endifif( sharpingBuffer.GetSmoothVal() < sharpingResetVal){AddReward(-1f);judge.Reset();return;}}lastReward = (velocityAngleCoef + velocityCoef) * 0.02f + (lookAngle+upAngle) * 0.01f + (leftThighAngle+rightThighAngle+leftUpperArmAngle+rightUpperArmAngle) * 0.005f+ (spineUpAngle+rootUpAngle) * 0.005f+ (tailAngle) * 0.006f+ (1f - exertionRatio) * 0.004f;if(useClampReward){lastReward = lastReward+clampReward;if(lastReward < 0f) lastReward = 0f;}totalReward += lastReward;AddReward( lastReward );}// else if(targetDistance > 1.5f)else{// AddReward(1f);judge.survived++;judge.Reset();return;}}}

//大致來說,
--1.獎勵視線,並使用Force Sharping
--2.獎勵投影至"跑動推薦向量"的速度和角度,並使用Force Sharping
--3.獎勵四個大腿的Side Look
--4.獎勵尾巴符合指定角度
--5.獎勵減少動作變化

4.Force Sharping改為有容錯空間,但是容許值逆向Sharping
允許角色在5秒內發生總計2秒以內的失誤,希望藉此讓角色就算輕微失衡也能嘗試自行修正
但是容許值是逆向Sharping,會在開始Force Sharping後兩秒才逐步放寬標準

實驗時間:
Step: 5e7
Time Elapsed: 124862s (34.68hr)

實驗結果:
實驗結果為成功

狼不管尺寸都能快速奔跑,唯獨問題是跑法很不帥氣
沒有像狼的奔騰方式

研究了一下貓犬奔騰時,會變成前後腿同手同腳的理由
據說是貓狗比起一般動物,更注重爆發力,所以會利用脊椎的肌群來提高爆發力

但這樣到底該如何處理狼的問題呢?

幾個可能選項
1.拉高Force Sharping銳利度
逼迫狼必須用更有爆發力的跑法,但問題是不知道要多銳利

2.強制誘導
直接誘導狼前腿和後腿都必須同步,但這個做法很糟,尤其狼也不是真的同步

3.調節關節力量
讓狼會自然演化成依賴脊椎發力,但不知道要調到多少

4.阻絕側向搖擺
例如狼幾乎完全不能左右搖擺,那就有可能不會想用兩腿交錯,而會傾向兩腿同步
好,決定了

下個實驗是狼追逐
1.阻絕側向搖擺
2.強制誘導
鼓勵前腿和後腿的同步,鼓勵方式為投影到flatLeftDir向量平面的角度,角度越接近得分越高,而且角度後期落差必須相當小

創作回應

更多創作