ã³ã³ãããŒã©ãŒã®å©ããåããã«å¶åŸ¡ã§ããã³ã³ãã¥ãŒã¿ãŒã·ã¹ãã ã¯ã人éãšã³ã³ãã¥ãŒã¿ãŒã®çžäºäœçšã®æ°ãã段éã§ãã ãã®é åã«ã¯ããžã§ã¹ãã£èªèãé³å£°èªèãé¡èªèãã¢ãŒã·ã§ã³ãã©ããã³ã°ãç°å¢ã®åæ§ç¯ãªã©ãç©ççç°å¢ãèªèããæè¡ãå«ãŸããŸãã Intel RealSense F200ããã³R200ã«ã¡ã©ã¯ããã®åéã§å€ãã®æ©èœãæäŸããŸãã ã«ã¡ã©ã®æ·±åºŠã決å®ããŠæ®åœ±ããæ©èœã®ãããã§ãF200ãšR200ã¯3次å ç°å¢ãæ§ç¯ããç°å¢ã«é¢é£ããããã€ã¹ã®åãã远跡ããããšãã§ããŸãã ç°å¢ã®åæ§ç¯ãšã¢ãŒã·ã§ã³ãã©ããã³ã°ã«ãããä»®æ³ãªããžã§ã¯ããçŸå®ã®äžçã«åãŸãä»®æ³çŸå®ã®æ©èœãå®çŸã§ããŸãã
ãã®èšäºã®ç®çã¯ãèªåŸããã²ãŒã·ã§ã³ã«ç²Ÿéããæ¡åŒµçŸå®ã¢ããªã±ãŒã·ã§ã³ã§ã®ã¢ããªã±ãŒã·ã§ã³ã説æããããšã§ãã éçºããäŸã§ã¯ãIntel RealSense R200ã«ã¡ã©ãšUnity 3Dã²ãŒã ãšã³ãžã³ã䜿çšããŠããŸãã äºåã«Intel RealSense SDKããã³Unityã®æ©èœãç解ããŠããããšããå§ãããŸãã Intel RealSense SDKãšUnityã®çµ±åã«ã€ããŠã¯ãUnityããã³Intel RealSense 3Dã«ã¡ã©ã䜿çšããã²ãŒã ã®éçº ãšãIntel RealSense R200ã䜿çšããUnityã®æ¡åŒµçŸå®ãåç §ããŠãã ãã ã
Intel RealSenseã«ã¡ã©ã¯ãæ¡åŒµçŸå®ã¢ããªã±ãŒã·ã§ã³ã«ããŒã¿ãæäŸã§ããŸãããæ¬åœã«èå³æ·±ãä»®æ³äžçãäœæããã®ã¯éçºè 次第ã§ãã ç掻ç°å¢ãäœæãã1ã€ã®æ¹æ³ã¯ãã¹ã¿ã³ãã¢ãã³ãšãŒãžã§ã³ãã䜿çšããããšã§ãã èªåŸãšãŒãžã§ã³ãã¯ã人工ç¥èœã䜿çšããŠç¬ç«ããŠåäœãããªããžã§ã¯ãã§ãã 人工ç¥èœã¯ããšãŒãžã§ã³ããåŸããªããã°ãªããªãéçšãã©ã¡ãŒã¿ãŒãšã«ãŒã«ã決å®ããŸãã ãšãŒãžã§ã³ãã¯ãããã眮ãããŠããç°å¢ã®ç¶æ ã«ãªã¢ã«ã¿ã€ã ã§åçã«å¿çãããããã¢ã¯ã·ã§ã³ã®ååãåçŽã§ãã£ãŠããè€éãªåäœã¢ãã«ãæã€ããšãã§ããŸãã
èªåŸãšãŒãžã§ã³ãã¯ããŸããŸãªåœ¢ã§ååšã§ããŸããããã®èª¬æã§ã¯ã移åããã³ããã²ãŒãã§ãããšãŒãžã§ã³ãã«çŠç¹ãåœãŠãŸãã ãã®ãããªãšãŒãžã§ã³ãã«ã¯ããã¬ã€ã€ãŒãå¶åŸ¡ããªãã²ãŒã ãã£ã©ã¯ã¿ãŒïŒNPCïŒããã¢ãã¡ãŒã·ã§ã³ããã°ã©ã ã®ãã¬ãŒãã³ã°ã§çŸ€ãããªãé³¥ãå«ãŸããŸãã ãšãŒãžã§ã³ãã®ç®æšã¯ã¢ããªã±ãŒã·ã§ã³ã«ãã£ãŠç°ãªããŸããã移åãšããã²ãŒã·ã§ã³ã®ååã¯ãã¹ãŠã®å Žåã§åãã§ãã
èªåŸèªæ³
ãšãŒãžã§ã³ãã®ããã²ãŒã·ã§ã³ã¯ãããŸããŸãªæ¹æ³ã§å®è¡ã§ããŸããå®è£ ã®èŠ³ç¹ãšãªãœãŒã¹ã®éäžåºŠã®äž¡æ¹ã®ç¹ã§ãã·ã³ãã«ãšè€éã®äž¡æ¹ã§ãã æãç°¡åãªã¢ãããŒãã¯ããšãŒãžã§ã³ãããã©ããã¹ã決å®ããããšã§ãã ãŠã§ã€ãã€ã³ããéžæããããšããšãŒãžã§ã³ãã¯ããã«åãã£ãŠçŽç·ã§ç§»åããŸãã ãã®ã¢ãããŒãã¯ç°¡åã«å®è£ ã§ããŸããããã®ã¢ããªã±ãŒã·ã§ã³ã«ã¯ããã€ãã®åé¡ããããŸãã æãæçœãªã®ã¯ããšãŒãžã§ã³ããšãŠã§ã€ãã€ã³ãã®éã«çŽæ¥ã®ãã¹ããªãå Žåã¯ã©ããªããŸããïŒå³1ïŒã
å³1.ãšãŒãžã§ã³ãã¯ãã€ã¬ã¯ããã¹ã«æ²¿ã£ãŠã¿ãŒã²ããã«åãã£ãŠç§»åããŸããããã¹ã¯é害ç©ã«ãã£ãŠãããã¯ãããŠããŸãã ã泚æ 説æãããŠãã質åã¯ã2次å 空éãš3次å 空éã®äž¡æ¹ã®ããã²ãŒã·ã§ã³ã«é©çšã§ããŸãã ããã§ã¯2次å 空éã䜿çšããŠèª¬æããŸã
é害ç©ãé¿ããããã«ããŠã§ã€ãã€ã³ããè¿œå ããå¿ èŠããããŸãïŒå³2ïŒã
å³2.ãšãŒãžã§ã³ããé害ç©ãåé¿ã§ããããã«ãè¿œå ã®ãŠã§ã€ãã€ã³ããè¿œå ãããŸã
å€æ°ã®é害ç©ããã倧ããªå°å³ã«ã¯ãããå€ãã®ãŠã§ã€ãã€ã³ããšã«ãŒãããããŸãã ããã«ããŠã§ã€ãã€ã³ãã®å¯åºŠãäžãããšïŒå³3ïŒãããå¹ççãªã«ãŒããã¬ã€ã¢ãŠãããã®ã«åœ¹ç«ã¡ãŸãïŒç®çå°ãŸã§ã®ãšãŒãžã§ã³ãã®ãã¹ãçããªããŸãïŒã
å³3.ããããµã€ãºã倧ãããªããšããŠã§ã€ãã€ã³ããšå¯èœãªã«ãŒãã®æ°ãå¢ããŸãã
ãŠã§ã€ãã€ã³ããå€æ°ããå Žåãäºãã«é£æ¥ããŠããªã2ã€ã®ãŠã§ã€ãã€ã³ãéã«ã«ãŒããæ§ç¯ããæ¹æ³ãå¿ èŠã§ãã ãã®åé¡ã¯ãéãèŠã€ããããšåŒã°ããŸãã ãã¹ã®æ€çŽ¢ã¯ãã°ã©ãçè«ãšå¯æ¥ã«é¢é£ããŠãããããã²ãŒã·ã§ã³ã ãã§ãªãå€ãã®åéã«é©çšãããŸãã åœç¶ããã®åéã§ã¯å€ãã®ç 究ãè¡ãããŠããããã¹ãèŠã€ããããã®ããŸããŸãªåé¡ã解決ããããã«å€ãã®ã¢ã«ãŽãªãºã ãäœæãããŠããŸãã æãããç¥ãããŠãããã¹æ€çŽ¢ã¢ã«ãŽãªãºã ã®1ã€ã¯A *ã§ãã ãã®ã¢ã«ãŽãªãºã ã§ã¯ãé£æ¥ãããŠã§ã€ãã€ã³ãéãç®çå°ã«åãã£ãŠç§»åãã蚪åãããã¹ãŠã®ãŠã§ã€ãã€ã³ããšãããã«æ¥ç¶ããããã¹ãŠã®ãŠã§ã€ãã€ã³ãã®ããããäœæããŸãã å®å ã«å°éãããšãã¢ã«ãŽãªãºã ã¯äœæããããããã䜿çšããŠãã¹ãèšç®ããŸãã ãã®åŸããšãŒãžã§ã³ãã¯ãã®ãã¹ã«æ²¿ã£ãŠç§»åã§ããŸãã ã¢ã«ãŽãªãºã A *ã¯ã䜿çšå¯èœãªãã¹ãŠã®ã¹ããŒã¹ã§ã®æ€çŽ¢ãæäŸããŸããããããã£ãŠãæ§ç¯ããããã¹ã¯åžžã«æé©ãšã¯èšããŸããã ã³ã³ãã¥ãŒãã£ã³ã°ãªãœãŒã¹ãžã®è² è·ã®èŠ³ç¹ããããã®ãããªã¢ã«ãŽãªãºã ã®å¹çã¯éåžžã«é«ããªã£ãŠããŸãã
å³4. A *ã¢ã«ãŽãªãºã ãããããèµ°æ»ããã¿ãŒã²ããAnimationïŒSubh83 / CC BY 3.0ãžã®ã«ãŒããèŠã€ããããšããŸã
ã¢ã«ãŽãªãºã A *ã¯ããã®æ§è³ªäžãé害ç©ã®è¿œå ãé€å»ãå¢çã®ç§»åãªã©ãç°å¢ã®å€åã«é©å¿ã§ããŸããã æ¡åŒµçŸå®ç°å¢ã¯æ¬è³ªçã«åçã§ãããã®ãããªç°å¢ã¯ããŠãŒã¶ãŒãšç©çç空éã®åãã«å¿ããŠäœæããã³å€æŽãããããã§ãã
åçãªç°å¢ã§ã¯ããšãŒãžã§ã³ãããªã¢ã«ã¿ã€ã ã§æ±ºå®ãäžãããšãæãŸããã§ãã ãã®ãããªæ±ºå®ã¯ããšãŒãžã§ã³ãã®ç°å¢ã«é¢ããçŸåšã®ç¥èã«åºã¥ããŠè¡ãããã¹ãã§ãã ãããã£ãŠããšãŒãžã§ã³ãããªã¢ã«ã¿ã€ã ã§ææ決å®ãšè¡åãè¡ããããã«ãæ§é ã決å®ããå¿ èŠããããŸãã ããã²ãŒã·ã§ã³ã«é¢ããŠã䟿å©ã§äžè¬çãªã¢ãããŒãã¯ãåäœã®æ§é ã3ã€ã®ã¬ãã«ã«åå²ãããã®ã§ãã
- ã¢ã¯ã·ã§ã³ã®éžæã¯ãç®æšãèšå®ãããããã®ç®æšãéæããæ¹æ³ã決å®ããããšã§æ§æãããŸãã ããšãã°ããŠãµã®ã¯é€ãæ±ããŠéåãåãåããŸãããæé£è
ãè¿ãã«çŸãããšããŠãµã®ã¯éããŸãã æéç¶æ
ãã·ã³ïŒæéç¶æ
ãã·ã³ïŒã¯ããšãŒãžã§ã³ãã®ç¶æ
ãšç¶æ
ãå€åããæ¡ä»¶ã決å®ããããããã®åäœã®å®è£
ã«äœ¿çšãããšäŸ¿å©ã§ãã
- ã¬ã€ãã³ã¹ã¯ããšãŒãžã§ã³ãã®çŸåšã®ç¶æ
ã«åºã¥ããåãã®èšç®ã§ãã ããšãã°ãæé£è
ããŠãµã®ãè¿œããããŠããå ŽåããŠãµã®ã¯æé£è
ããéããªããã°ãªããŸããã ã¬ã€ãã³ã¹ã¯ãåãã®å€§ãããšæ¹åã®äž¡æ¹ãèšç®ããŸãã
- 移åã¯ããšãŒãžã§ã³ãã移åããã¡ã«ããºã ã§ãã ãŠãµã®ãç·ãè»ãå®å®è¹ã¯ããŸããŸãªæ¹æ³ã§åããŸãã åãã¯ãåãã®æ¹æ³ïŒããšãã°ãèãè»èŒªããã±ãããšã³ãžã³ã®å©ããåããŠïŒãšããã®åãã®ãã©ã¡ãŒã¿ãŒïŒããšãã°ã質éãæ倧é床ãæ倧åãªã©ïŒã®äž¡æ¹ã決å®ããŸãã
ãããã®ã¬ãã«ãäžç·ã«ãªã£ãŠããšãŒãžã§ã³ãã®äººå·¥ç¥èœã圢æããŸãã 次ã®ã»ã¯ã·ã§ã³ã§ã¯ãããã3ã€ã®ã¬ãã«ã®å®è£ ã瀺ãUnityã¢ããªã±ãŒã·ã§ã³ã®äŸã瀺ããŸãã 次ã«ãR200ã«ã¡ã©ã䜿çšããŠãæ¡åŒµçŸå®ã¢ããªã±ãŒã·ã§ã³ã«èªåŸããã²ãŒã·ã§ã³ãåã蟌ã¿ãŸãã
ãªãã©ã€ã³ããã²ãŒã·ã§ã³ã®å®è£
ãã®ã»ã¯ã·ã§ã³ã§ã¯ã移åããå§ããŠãèªåŸããã²ãŒã·ã§ã³ã®ããã®Unityã·ãŒã³ã®åäœãã©ãããã©ãŒã ã«ã€ããŠèª¬æããŸãã
oveåã
ãšãŒãžã§ã³ãã®åãã¯ã ãã¥ãŒãã³ååŠã®æ³åã«åºã¥ããŠããŸãã質éã«åãå ãããããšãå éãçºçããŸãã ç§ãã¡ã¯ãããããæ¹åããåãå ããããšãã§ãããåäžã«ååžããäœéãæã€åçŽåãããã¢ãã«ã䜿çšããŸãã åããå¶éããããã«ãæ倧åãšæ倧é床ãèšå®ãããŸãïŒã³ãŒããã©ã°ã¡ã³ã1ïŒã
public float mass = 1f; // Mass (kg) public float maxSpeed = 0.5f; // Maximum speed (m/s) public float maxForce = 1f; // "Maximum force (N)
ã¹ãããã1.ãšãŒãžã§ã³ãã®ç§»åã¢ãã«
ãšãŒãžã§ã³ãã«ã¯ãèµ·åæã«åæåãããrigidbodyããã³colliderã³ã³ããŒãã³ããå¿ èŠã§ãïŒã³ãŒãã¹ãããã2ãåç §ïŒã ã¢ãã«ãåçŽã«ããããã«ãéåã¯é€å€ãããŠããŸããããªã³ã«ããããšãã§ããŸãã
private void Start () { // Initialize the rigidbody this.rb = GetComponent<rigidbody> (); this.rb.mass = this.mass; this.rb.useGravity = false; // Initialize the collider this.col = GetComponent<collider> (); }
ã³ãŒãã¹ãããã2ãrigidbodyããã³colliderã³ã³ããŒãã³ãã¯StartïŒïŒã§åæåãããŸãã
ãšãŒãžã§ã³ãã¯ã FixedUpdateïŒïŒã¹ãããã§ãªãžããããã£ã«åãå ããããšã§ç§»åããŸãïŒã³ãŒãã¹ãããã3ãåç §ïŒã FixedUpdateïŒïŒã¯UpdateïŒïŒãšåæ§ã«æ©èœããŸããã UpdateïŒïŒãšã¯ç°ãªããåãééã§å®è¡ãããããšãä¿èšŒãããŠããŸãã Unityãšã³ãžã³ã¯ã FixedUpdateïŒïŒã¹ãããã®å®äºåŸã«ç©çåŠïŒãœãªããã䜿çšããæäœïŒãèšç®ããŸãã
private void FixedUpdate () { Vector3 force = Vector3.forward; // Upper bound on force if (force.magnitude > this.maxForce) { force = force.normalized * this.maxForce; } // Apply the force rb.AddForce (force, ForceMode.Force); // Upper bound on speed if (rb.velocity.magnitude > this.maxSpeed) { rb.velocity = rb.velocity.normalized * this.maxSpeed; } }
ã³ãŒãã¹ãããã3ãåã¯FixedUpdateïŒïŒã¹ãããã§åäœã«é©çšãããŸãã ãã®äŸã§ã¯ããšãŒãžã§ã³ãã¯Z軞ã«æ²¿ã£ãŠç§»åããŸã
åã®å€§ããããšãŒãžã§ã³ãã®æ倧匷床ãè¶ ããå Žåã倧ããã®åŒ·åºŠãæ倧åã«çãããªãããã«èª¿æŽãããŸãïŒæ¹åã¯ç¶æãããŸãïŒã AddForceïŒïŒé¢æ°ã¯ã æ°å€ç©åã«ããåãé©çšããŸãã
åŒ1.é床ã®æ°å€ç©åã AddForceïŒïŒé¢æ°ããã®èšç®ãå®è¡ããŸãã
ããã§ã Îœ1ã¯æ°ããé床ã Îœ0ã¯å€ãé床ã fã¯åã mã¯è³ªéã Îtã¯æŽæ°éã®æéééã§ãïŒããã©ã«ãã§ã¯ãUnityã®åºå®æéã¹ãããã¯0.02 sã§ãïŒã é床å€ãæ倧ãšãŒãžã§ã³ãé床ãè¶ ããå Žåãæ倧é床ãšäžèŽããããã«èª¿æŽãããŸãã
ã¬ã€ãã³ã¹
ã¬ã€ãã³ã¹ã¯ãéåã¢ãã«ã«äžããããåãèšç®ããŸãã é害ç©ã®æ¢çŽ¢ãå°çãåé¿ã®3ã€ã®ã¬ã€ãã³ã¹ã¢ã«ãŽãªãºã ãé©çšãããŸãã
æ€çŽ¢ãã
ãæ€çŽ¢ãåäœã¯ããªããžã§ã¯ããã§ããã ãæ©ãã¿ãŒã²ããã«åãã£ãŠç§»åããããšããŸãã ãã®åäœã®æãŸããé床ã¯ãæ倧é床ã§ã¿ãŒã²ããã«çŽæ¥ç§»åããããšã§ãã èªå°åã¯ãåžæã®ãšãŒãžã§ã³ãé床ãšçŸåšã®ãšãŒãžã§ã³ãé床ã®å·®ãšããŠèšç®ãããŸãïŒå³5ïŒã
å³5.ãæ€çŽ¢ãããã€ãã¢ãŒã¯ãããŒãã¯ãŒãé©çšããŠãçŸåšã®é床ãåžæã®é床ã«å€æŽããŸã
å®è£ ïŒã³ãŒãã¹ãããã4ïŒã¯ãæåã«ãšãŒãžã§ã³ããšã¿ãŒã²ããéã®ãã€ã¢ã¹ãæ£èŠåããããã«æ倧é床ãæããããšã«ãããç®çã®ãã¯ãã«ãèšç®ããŸãã æ»ãæ瀺åã¯ãç®çã®é床ããçŸåšã®åäœé床ãåŒãããã®ã§ãã
private Vector3 Seek () { Vector3 desiredVelocity = (this.seekTarget.position - this.transform.position).normalized * this.maxSpeed; return desiredVelocity - this.rb.velocity; }
ã³ãŒãã¹ãããã4.åäœãæ€çŽ¢ã
ãšãŒãžã§ã³ãã¯ãæ€çŽ¢ãã¢ã«ãŽãªãºã ã䜿çšãã FixedUpdateïŒïŒã§åãèšç®ãããšãã«SeekïŒïŒãåŒã³åºããŸãïŒã³ãŒãã¹ãããã5ïŒã
private void FixedUpdate () { Vector3 force = Seek (); ...
ã³ãŒãã¹ãããã5. FixedUpdateïŒïŒã®SeekïŒïŒãåŒã³åºã
åäœäžã®ãæ€çŽ¢ãã¢ã«ãŽãªãºã ã®äŸããããª1ã«ç€ºããŸãããšãŒãžã§ã³ãã«ã¯ãåäœã®çŸåšã®é床ã瀺ãéãç¢å°ãšããã®æéééã§ã¬ã€ãã³ã¹ãé©çšãããããšã瀺ãèµ€ãç¢å°ãè£ åãããŠããŸãã
ãããª1.æåã¯ããšãŒãžã§ã³ãã®é床ã¯ã¿ãŒã²ããã®æ¹åã«åçŽã§ããããããšãŒãžã§ã³ãã¯æ²ç·ã«æ²¿ã£ãŠç§»åããŸã
å°ç
ãæ€çŽ¢ãã¢ã«ãŽãªãºã ã䜿çšãããšããšãŒãžã§ã³ãã¯å¯èœãªéãæé«é床ã§ç§»åããŠãããããã¿ãŒã²ãããéããŠç§»åããŸãã å°çã¢ã«ãŽãªãºã ã¯æ€çŽ¢ã¢ã«ãŽãªãºã ã«äŒŒãŠããŸãããéãã¯ã¿ãŒã²ããã§å®å šã«åæ¢ããããšããããšã§ãã ãã©ã¡ãŒã¿ãŒãã¹ããŒã€ã³ã°ååŸãã¯ããšãŒãžã§ã³ããã¹ããŒããŠã³ãå§ããã¿ãŒã²ããã«å°éããè·é¢ã決å®ããŸãã ãšãŒãžã§ã³ããæžéååŸå ã«ããå ŽåãæãŸããé床ã¯ãšãŒãžã§ã³ããšã¿ãŒã²ããéã®è·é¢ã«åæ¯äŸããŸãã æ倧åãæ倧é床ãããã³æžéååŸã«ãã£ãŠã¯ããã®åäœãå®å šã«åæ¢ããªãå ŽåããããŸãã
å°çåäœïŒã³ãŒãã¹ãããã6ïŒã¯ãæåã«ãšãŒãžã§ã³ããšã¿ãŒã²ããéã®è·é¢ãèšç®ããŸãã æžéé床ã¯ãæžéååŸã§å²ã£ãè·é¢ãŸã§æžéããæ倧é床ãšããŠèšç®ãããŸãã ç®çã®é床ã¯ãæå®ãããé床ãšæ倧é床ã®éã§æå°ã§ãã ãããã£ãŠãã¿ãŒã²ãããŸã§ã®è·é¢ãæžéååŸããå°ããå ŽåãæãŸããé床ã¯æžéé床ã§ãã ãã以å€ã®å Žåãç®çã®é床ã¯æ倧é床ã§ãã ãã®é¢æ°ã®æ®ãã®éšåã¯ãç®çã®é床ã§ãæ€çŽ¢ããšãŸã£ããåãããã«æ©èœããŸãã
// Arrive deceleration radius (m) public float decelerationRadius = 1f; private Vector3 Arrive () { // Calculate the desired speed Vector3 targetOffset = this.seekTarget.position - this.transform.position; float distance = targetOffset.magnitude; float scaledSpeed = (distance / this.decelerationRadius) * this.maxSpeed; float desiredSpeed = Mathf.Min (scaledSpeed, this.maxSpeed); // Compute the steering force Vector3 desiredVelocity = targetOffset.normalized * desiredSpeed; return desiredVelocity - this.rb.velocity; }
ã¹ãããã6.åäœãå°çã
ãããª2.ãå°çãã¢ã«ãŽãªãºã ã¯ãç®æšã«å°éãããšé床ãäœäžãããŸã
é害ç©åé¿
å°çããã³æ€çŽ¢ã¢ã«ãŽãªãºã ã¯ç®çå°ã«å°çããã®ã«æé©ã§ãããé害ã«å¯ŸåŠããããšã¯ã§ããŸããã åçãªç°å¢ã§ã¯ããšãŒãžã§ã³ãã¯æ°ãã«åºçŸããé害ãåé¿ã§ããå¿ èŠããããŸãã é害ç©åé¿ã¢ã«ãŽãªãºã ã¯ãææ¡ãããã«ãŒãã«æ²¿ã£ãŠãšãŒãžã§ã³ãã®åã®ãã¹ãåæããåé¿ãã¹ãé害ç©ããããã©ãããå€æããŸãã é害ç©ãæ€åºããããšãã¢ã«ãŽãªãºã ã¯ãšãŒãžã§ã³ããé害ç©ãšè¡çªããªãããã«ãšãŒãžã§ã³ãã®çµè·¯ãå€æŽããåãèšç®ããŸãïŒå³6ïŒã
å³6.çŸåšã®è»éäžã§é害ç©ãæ€åºãããå Žåãè¡çªåé¿åãè¿ãããŸã
é害ç©åé¿ã¢ã«ãŽãªãºã ã®å®è£ ïŒã³ãŒããã©ã°ã¡ã³ã7ïŒã¯ãã¹ãã£ã¢ãã£ã¹ãã䜿çšããŠè¡çªãæ€åºããŸãã ãã®å Žåãçäœã¯çŸåšã®åäœé床ãã¯ãã«ã«æ²¿ã£ãŠãªãªãŒã¹ãããè¡çªããšã«RaycastHitãè¿ãããŸãã çäœã¯ãšãŒãžã§ã³ãã®äžå¿ãã移åããŸãããã®ååŸã¯ããªããžã§ã¯ãã®è¡çªååŸãšãã©ã¡ãŒã¿ãŒãåé¿ååŸãã®å€ã®åèšã«çãããªããŸãã åé¿ååŸã䜿çšããŠããŠãŒã¶ãŒã¯ãšãŒãžã§ã³ãã®åšãã®ç©ºãã¹ããŒã¹ãç¹å®ã§ããŸãã çäœã®åãã®ç¯å²ã¯ããåæ¹æ€åºããã©ã¡ãŒã¿ãŒã«ãã£ãŠå¶éãããŸãã
// Avoidance radius (m). The desired amount of space between the agent and obstacles. public float avoidanceRadius = 0.03f; // Forward detection radius (m). The distance in front of the agent that is checked for obstacles. public float forwardDetection = 0.5f; private Vector3 ObstacleAvoidance () { Vector3 steeringForce = Vector3.zero; // Cast a sphere, that bounds the avoidance zone of the agent, to detect obstacles RaycastHit[] hits = Physics.SphereCastAll(this.transform.position, this.col.bounds.extents.x + this.avoidanceRadius, this.rb.velocity, this.forwardDetection); // Compute and sum the forces across all hits for(int i = 0; i < hits.Length; i++) { // Ensure that the collidier is on a different object if (hits[i].collider.gameObject.GetInstanceID () != this.gameObject.GetInstanceID ()) { if (hits[i].distance > 0) { // Scale the force inversely proportional to the distance to the target float scaledForce = ((this.forwardDetection - hits[i].distance) / this.forwardDetection) * this.maxForce; float desiredForce = Mathf.Min (scaledForce, this.maxForce); // Compute the steering force steeringForce += hits[i].normal * desiredForce; } } } return steeringForce; }
ã³ãŒã7ã®ã¹ãããããåäœãé害ç©ããã®åé¿ã
spherecastã䜿çšãããšã RaycastHitãªããžã§ã¯ãã®é åãè¿ãããŸãã RaycastHitãªããžã§ã¯ãã«ã¯ãè¡çªãŸã§ã®è·é¢ããè¡çªãçºçãããµãŒãã§ã¹ã®å¹³é¢ã®æ³ç·ãªã©ã®è¡çªæ å ±ãå«ãŸããŠããŸãã æ³ç·ã¯ãå¹³é¢ã«åçŽãªãã¯ãã«ã§ãã ããã䜿çšããŠããšãŒãžã§ã³ããè¡çªç¹ããé ãããããšãã§ããŸãã åã®å€§ããã¯ãæ倧åãè¡çªãŸã§ã®è·é¢ã«åæ¯äŸãããããšã«ãã£ãŠæ±ºå®ãããŸãã åè¡çªã®åãåèšãããçµæã¯1ã€ã®æéééã§ã®åèšåé¿åã«ãªããŸãã
ããè€éãªåäœãååŸããã«ã¯ãäžåºŠã«è€æ°ã®ã¢ã«ãŽãªãºã ã䜿çšã§ããŸãïŒã³ãŒããã©ã°ã¡ã³ã8ïŒã é害ç©åé¿ã¢ã«ãŽãªãºã ã¯ãä»ã®ã¢ã«ãŽãªãºã ãšãšãã«äœ¿çšããå Žåã«ã®ã¿åœ¹ç«ã¡ãŸãã ãã®äŸïŒãããª3ïŒã§ã¯ããé害ç©ã®åé¿ããå°çã¢ã«ãŽãªãºã ãšå ±ã«äœ¿çšãããŠããŸãã è¡åã®ã¢ã«ãŽãªãºã ã¯ãåçŽã«åãå ç®ããããšã§çµåãããŸãã ãã¥ãŒãªã¹ãã£ãã¯ãªã¡ã«ããºã ã䜿çšããŠåŒ·å¶åªå 床ã®éã¿ä¿æ°ã決å®ãããããè€éãªã¹ããŒã ãå¯èœã§ãã
private void FixedUpdate () { // Calculate the total steering force by summing the active steering behaviors Vector3 force = Arrive () + ObstacleAvoidance(); ...
ã³ãŒã8ã®ã¹ãããããã¢ã«ãŽãªãºã ãå°çããšãé害ç©ããã®åé¿ãã¯ãåãè¿œå ããããšã«ããåæã«äœ¿çšãããŸãã
ãããª3.ãšãŒãžã§ã³ãã¯ããå°çããšãé害ã®åé¿ãã®2çš®é¡ã®åäœãåæã«äœ¿çšããŸãã
actionè¡åã®éžæ
ã¢ã¯ã·ã§ã³ã®éžæã¯ããšãŒãžã§ã³ãã«ããå ±éã®ç®æšãšææ決å®ã®èšå®ã§ãã ãšãŒãžã§ã³ãã®å®è£ ã«ã¯ããå°çãã¢ã«ãŽãªãºã ãšãé害ã®åé¿ãã¢ã«ãŽãªãºã ã®çµã¿åããã®åœ¢ã§ã¢ã¯ã·ã§ã³ãéžæããããã®åçŽãªã¢ãã«ããã§ã«å«ãŸããŠããŸãã ãšãŒãžã§ã³ãã¯ã¿ãŒã²ããã«å°éããããšããŸãããé害ç©ãæ€åºããããšããã®ãã¹ãå€æŽãããŸãã é害ç©åé¿ã¢ã«ãŽãªãºã ã®åé¿ååŸãšåæ¹æ€åºãã©ã¡ãŒã¿ãŒã¯ãå®è¡ãããã¢ã¯ã·ã§ã³ã決å®ããŸãã
R200ã«ã¡ã©ã®çµ±å
ããã§ããšãŒãžã§ã³ãã¯ç¬ç«ããŠç§»åã§ããããã«ãªããæ¡åŒµçŸå®ã¢ããªã±ãŒã·ã§ã³ã«å«ããããšãã§ããŸãã
次ã®äŸã¯ãIntel RealSense SDKã®äžéšã§ããScene Perceptionã®äŸã«åºã¥ããŠããŸãã ãã®ã¢ããªã±ãŒã·ã§ã³ã¯Scene Perceptionã䜿çšããŠ3次å ã¢ãã«ãäœæãããŠãŒã¶ãŒã¯3次å 空éã§ã¿ãŒã²ãããèšå®ããã³ç§»åã§ããŸãã ãã®åŸããšãŒãžã§ã³ãã¯äœæããã3次å ã¢ãã«ã移åããŠç®æšãéæã§ããŸãã
âã·ãŒã³ãããŒãžã£ãŒ
ã¹ã¯ãªããã·ãŒã³ãããŒãžã£ãŒã¯ãã·ãŒã³ãåæåãããŠãŒã¶ãŒã³ã³ãããŒã«ãåŠçããŸãã å¯äžã®ã³ã³ãããŒã«ã¯ã¿ããïŒãŸãã¯ããã€ã¹ãã¿ããããµããŒãããŠããªãå Žåã¯ããŠã¹ã¯ãªãã¯ïŒã§ãã ã¿ãããã€ã³ãããã®ã¬ã€ãã¬ãŒã·ã³ã°ã«ãããäœæããã3次å ã¢ãã«ã«ã¿ãããããã©ããã決ãŸããŸãã æåã®ã¿ããã§3次å ã¢ãã«ã«ã¿ãŒã²ãããäœæããã2çªç®ã®ã¿ããã§ãšãŒãžã§ã³ããäœæããããã®åŸã®åã¿ããã§ã¿ãŒã²ããã®äœçœ®ã移åããŸãã å¶åŸ¡ããžãã¯ã¯ãã¹ããŒããã·ã³ïŒã³ãŒããã©ã°ã¡ã³ã9ïŒã«ãã£ãŠåŠçãããŸãã
// State machine that controls the scene: // Start => SceneInitialized -> TargetInitialized -> AgentInitialized private enum SceneState {SceneInitialized, TargetInitialized, AgentInitialized}; private SceneState state = SceneState.SceneInitialized; // Initial scene state. private void Update () { // Trigger when the user "clicks" with either the mouse or a touch up gesture. if(Input.GetMouseButtonUp (0)) { TouchHandler (); } } private void TouchHandler () { RaycastHit hit; // Raycast from the point touched on the screen if (Physics.Raycast (Camera.main.ScreenPointToRay (Input.mousePosition), out hit)) { // Only register if the touch was on the generated mesh if (hit.collider.gameObject.name == "meshPrefab(Clone)") { switch (this.state) { case SceneState.SceneInitialized: SpawnTarget (hit); this.state = SceneState.TargetInitialized; break; case SceneState.TargetInitialized: SpawnAgent (hit); this.state = SceneState.AgentInitialized; break; case SceneState.AgentInitialized: MoveTarget (hit); break; default: Debug.LogError("Invalid scene state."); break; } } } }
ã³ãŒãã¹ãããã9.ãµã³ãã«ã¢ããªã±ãŒã·ã§ã³ã®ã¿ãããã³ãã©ãŒãšã¹ããŒããã·ã³
Scene Perceptionã³ã³ããŒãã³ãã¯ãå€ãã®å°ããª3次å ã¢ãã«ã圢æããŸãã ãã®ãããªã¢ãã«ã«ã¯ãéåžžã30å以äžã®é ç¹ããããŸãã é ç¹ã®äœçœ®ã¯ç°ãªãå Žåãããããã®çµæãäžéšã®ã¢ãã«ã¯ãããããé 眮ãããŠãããµãŒãã§ã¹ã«å¯ŸããŠãããã«åŸããŠããŸãã ãªããžã§ã¯ããã¢ãã«ã®äžéšã«ããå ŽåïŒããšãã°ãã¿ãŒã²ãããŸãã¯ãªããžã§ã¯ãïŒããªããžã§ã¯ãã®åãã¯æ£ãããããŸããã ãã®åé¡ãåé¿ããã«ã¯ã3次å ã¢ãã«ã®å¹³åæ³ç·ã䜿çšããŸãïŒã³ãŒãã¹ãããã10ïŒã
private Vector3 AverageMeshNormal(Mesh mesh) { Vector3 sum = Vector3.zero; // Sum all the normals in the mesh for (int i = 0; i < mesh.normals.Length; i++){ sum += mesh.normals[i]; } // Return the average return sum / mesh.normals.Length; }
ã³ãŒãã®äžéš10. 3次å ã¢ãã«ã®å¹³åæ³ç·ã®èšç®
âã¢ã»ã³ããªã¢ã»ã³ããª
ãã®äŸã®ããã«éçºããããã¹ãŠã®ã³ãŒãã¯ãGithub Webãµã€ãã§å ¥æã§ããŸãã
次ã®æé ã§ã¯ãScene ManagerãšãšãŒãžã§ã³ãã®å®è£ ãIntel RealSenseã¢ããªã±ãŒã·ã§ã³ã«çµ±åããŸãã
- Intel RealSense SDK RSSDK \ framework \ Unityãã©ã«ããŒã§RF_ScenePerceptionã®äŸãéããŸãã
- AutoNavAR Unityããã±ãŒãžãããŠã³ããŒãããŠã€ã³ããŒãããŸãã
- Assets / AutoNavAR / Scenes /ãã©ã«ããŒã§RealSenseExampleSceneãéããŸãã
- Intel RealSense R200ã«ã¡ã©ãæèŒããäºææ§ã®ããããã€ã¹ã§ã¢ããªã±ãŒã·ã§ã³ããã«ãããŠå®è¡ããŸãã
ãããª4. Intel RealSense R200ã«ã¡ã©ãšã®çµ±å
èªåŸèªæ³ã®ãããªãéçº
R200ã«ã¡ã©ãåããæ¡åŒµçŸå®ã¢ããªã±ãŒã·ã§ã³ã§ã®ã¹ã¿ã³ãã¢ãã³ãšãŒãžã§ã³ãã瀺ãäŸãéçºããŸããã ãã®äœæ¥ãéçºãããšãŒãžã§ã³ãã®ãåçæ§ããšãªã¢ãªãºã ãé«ããã«ã¯ãããã€ãã®æ¹æ³ããããŸãã
ãšãŒãžã§ã³ããšããŠãåçŽåãããæ©æ¢°ã¢ãã«ãã質éã®åäžãªååžãšãšãã«ãæ¹åã®åãã®å¶éãªãã§äœ¿çšãããŸããã 質éãäžåäžã«åæ£ããã身äœã«ãããåãå¶éããããããå®å šãªã¢ãã«ãéçºã§ããŸãïŒããšãã°ãç°ãªãå éåãšå¶ååãæã€è»ãã¡ã€ã³ãšã³ãžã³ãšãµã€ãã·ã£ã³ããšã³ãžã³ãæã€å®å®è¹ïŒã æ©æ¢°ã¢ãã«ãããæ£ç¢ºã«å®è¡ãããã»ã©ãåãã¯ãããªã¢ã«ã«ãªããŸãã
ã¯ã¬ã€ã°ã¬ã€ãã«ãºã¯ãã¢ãã¡ãŒã·ã§ã³ãšã²ãŒã ã®ã³ã³ããã¹ãã§è¡åã¬ã€ãã³ã¹ã¢ã«ãŽãªãºã ã詳现ã«èª¬æããæåã®äººç©ã§ãã ãã®äŸã§ç€ºããã¢ã«ãŽãªãºã ãæ€çŽ¢ãããå°çãããã³ãé害ç©ã®åé¿ãã¯ã 圌ã®ç 究ã«åºã¥ããŠäœæãããŠããŸãã ã¬ã€ãã«ãºã¯ãé£è¡ãã¹ããŒãã³ã°ãæŸæµªã調æ»ãé害ç©ã®åé¿ãçµè·¯ã®è¿œè·¡ãªã©ãä»ã®è¡åã¢ã«ãŽãªãºã ã«ã€ããŠèª¬æããŸããã èæ ®ãããã°ã«ãŒãè¡åã¢ã«ãŽãªãºã ã«ã¯ããåé¢ãããçµ±åããããã³ãæ§ç¯ããå«ãŸããŸãã å¥ã®æçšãªãªãœãŒã¹ã¯ãMat Bucklandã®ãã²ãŒã çšã®äººå·¥ç¥èœã®ããã°ã©ãã³ã°ãã§ãã åäœã¢ã«ãŽãªãºã ã®å®è£ ãšãã¹ããŒããã·ã³ããã¹æ€çŽ¢ãªã©ããã®ä»ã®å€ãã®åé¡ã«ã€ããŠèª¬æããŠããŸãã
ãã®äŸã§ã¯ããå°çãããã³ãé害ã®åé¿ãã¬ã€ãã³ã¹ã¢ã«ãŽãªãºã ããšãŒãžã§ã³ãã«åæã«é©çšãããŸãã ãããã£ãŠãä»»æã®æ°ã®åäœã¢ã«ãŽãªãºã ãçµã¿åãããŠãããè€éãªã¢ãã«ãååŸã§ããŸãã ããšãã°ãããã€ãã¢ã¢ã«ãŽãªãºã ã¯ãåé¢ãããŒãžãããã³æ§ç¯ã«åºã¥ããŠããŸãã ç°ãªãåäœã¢ã«ãŽãªãºã ã®çµã¿åããã«ãããäžèªç¶ãªçµæãçããå ŽåããããŸãã ãã®ãããªã¢ã«ãŽãªãºã ã®ããŸããŸãªã¿ã€ããè©ŠããŠãæ°ããæ©èœãç¹å®ããããšããå§ãããŸãã
ããã«ãäžéšã®ãã¹æ€çŽ¢ææ³ã¯ãåçç°å¢ã§äœ¿çšããããã«èšèšãããŠããŸãã D *ã¢ã«ãŽãªãºã ã¯A *ã«è¿ãã§ãããæ°ãã芳枬ã«åºã¥ããŠãã¹ãæŽæ°ã§ããŸãïŒã€ãŸããé害ç©ãè¿œå ããã³åé€ããŸãïŒã D * Liteã¢ã«ãŽãªãºã ã¯D *ãšåãããã«æ©èœããå®è£ ãç°¡åã§ãã ãã¹ãã¡ã€ã³ãã£ã³ã°ãã¬ã€ãã³ã¹ãšãšãã«äœ¿çšã§ããŸãããŠã§ã€ãã€ã³ããèšå®ããŠãããã¬ã€ãã³ã¹ã䜿çšããŠããããè¿åã§ããŸãã
ã¢ã¯ã·ã§ã³ã®éžæã«ã€ããŠã¯ããã®èšäºã§ã¯èª¬æããŠããŸããããã²ãŒã çè«ã§åºãç 究ãããŠããŸãã ã²ãŒã çè«ã§ã¯ãæŠç¥ãšææ決å®ã®æ°åŠçåºç€ã調æ»ãããŸãã ã²ãŒã çè«ã¯ãçµæžåŠãæ¿æ²»åŠãå¿çåŠãå«ãå€ãã®åéã«é©çšãããŸãã èªåŸçãªãšãŒãžã§ã³ãã®å Žåãã²ãŒã çè«ã¯ã決å®ãè¡ãããæ¹æ³ãšã¿ã€ãã³ã°ãå¶åŸ¡ã§ããŸãã ã²ãŒã çè«101ïŒãŠã£ãªã¢ã ã¹ãããšã«ã«ããå®å šãªãªãã¡ã¬ã³ã¹ã¯ã YouTubeãããªã®ã·ãªãŒãºã®åªããéå§ãªãœãŒã¹ã§ãã
ãããã«
ãšãŒãžã§ã³ãã®åããè¡åãè¡åã調æŽããããã®ããŒã«ããããŸãã ãªãã©ã€ã³ããã²ãŒã·ã§ã³ã¯ãæ¡åŒµçŸå®ã¢ããªã±ãŒã·ã§ã³ã§äœæãããIntel RealSenseã«ã¡ã©ã®ãããªåçç°å¢ã«æé©ã§ãã åããšã¬ã€ãã³ã¹ã®åçŽãªã¢ãã«ã§ãããç°å¢ã«é¢ããäºåç¥èããªããŠãè€éãªåäœã圢æã§ããŸãã è±å¯ãªå©çšå¯èœãªã¢ãã«ãšã¢ã«ãŽãªãºã ã«ãããããããã¢ããªã±ãŒã·ã§ã³ã«ã¹ã¿ã³ãã¢ãã³ãœãªã¥ãŒã·ã§ã³ãæè»ã«å®è£ ã§ããŸãã