Beispiel #1
0
        /// <summary>
        /// Creates the RayPerceptionSensor.
        /// </summary>
        /// <param name="name">The name of the sensor.</param>
        /// <param name="rayInput">The inputs for the sensor.</param>
        public RayPerceptionSensor(string name, RayPerceptionInput rayInput)
        {
            m_Name = name;
            m_RayPerceptionInput = rayInput;

            SetNumObservations(rayInput.OutputSize());

            if (Application.isEditor)
            {
                m_DebugDisplayInfo = new DebugDisplayInfo();
            }
        }
        /// <summary>
        /// Evaluates the raycasts to be used as part of an observation of an agent.
        /// </summary>
        /// <param name="input">Input defining the rays that will be cast.</param>
        /// <returns>Output struct containing the raycast results.</returns>
        public static RayPerceptionOutput PerceiveStatic(RayPerceptionInput input)
        {
            RayPerceptionOutput output = new RayPerceptionOutput();

            output.rayOutputs = new RayPerceptionOutput.RayOutput[input.angles.Count];

            for (var rayIndex = 0; rayIndex < input.angles.Count; rayIndex++)
            {
                DebugDisplayInfo.RayInfo debugRay;
                output.rayOutputs[rayIndex] = PerceiveSingleRay(input, rayIndex, out debugRay);
            }

            return(output);
        }
        /// <summary>
        /// Creates the RayPerceptionSensor.
        /// </summary>
        /// <param name="name">The name of the sensor.</param>
        /// <param name="rayInput">The inputs for the sensor.</param>
        public RayPerceptionSensor(string name, RayPerceptionInput rayInput)
        {
            var numObservations = rayInput.OutputSize();

            m_Shape = new[] { numObservations };
            m_Name  = name;
            m_RayPerceptionInput = rayInput;

            m_Observations = new float[numObservations];

            if (Application.isEditor)
            {
                m_DebugDisplayInfo = new DebugDisplayInfo();
            }
        }
Beispiel #4
0
 internal void SetRayPerceptionInput(RayPerceptionInput rayInput)
 {
     // Note that change the number of rays or tags doesn't directly call this,
     // but changing them and then changing another field will.
     if (m_RayPerceptionInput.OutputSize() != rayInput.OutputSize())
     {
         Debug.Log(
             "Changing the number of tags or rays at runtime is not " +
             "supported and may cause errors in training or inference."
             );
         // Changing the shape will probably break things downstream, but we can at least
         // keep this consistent.
         SetNumObservations(rayInput.OutputSize());
     }
     m_RayPerceptionInput = rayInput;
 }
        /// <summary>
        /// Evaluate the raycast results of a single ray from the RayPerceptionInput.
        /// </summary>
        /// <param name="input"></param>
        /// <param name="rayIndex"></param>
        /// <param name="debugRayOut"></param>
        /// <returns></returns>
        internal static RayPerceptionOutput.RayOutput PerceiveSingleRay(
            RayPerceptionInput input,
            int rayIndex,
            out DebugDisplayInfo.RayInfo debugRayOut
            )
        {
            var unscaledRayLength  = input.rayLength;
            var unscaledCastRadius = input.castRadius;

            var extents            = input.RayExtents(rayIndex);
            var startPositionWorld = extents.StartPositionWorld;
            var endPositionWorld   = extents.EndPositionWorld;

            var rayDirection = endPositionWorld - startPositionWorld;
            // If there is non-unity scale, |rayDirection| will be different from rayLength.
            // We want to use this transformed ray length for determining cast length, hit fraction etc.
            // We also it to scale up or down the sphere or circle radii
            var scaledRayLength = rayDirection.magnitude;
            // Avoid 0/0 if unscaledRayLength is 0
            var scaledCastRadius = unscaledRayLength > 0 ?
                                   unscaledCastRadius * scaledRayLength / unscaledRayLength :
                                   unscaledCastRadius;

            // Do the cast and assign the hit information for each detectable tag.
            bool       castHit;
            float      hitFraction;
            GameObject hitObject;

            if (input.castType == RayPerceptionCastType.Cast3D)
            {
                RaycastHit rayHit;
                if (scaledCastRadius > 0f)
                {
                    castHit = Physics.SphereCast(startPositionWorld, scaledCastRadius, rayDirection, out rayHit,
                                                 scaledRayLength, input.layerMask);
                }
                else
                {
                    castHit = Physics.Raycast(startPositionWorld, rayDirection, out rayHit,
                                              scaledRayLength, input.layerMask);
                }

                // If scaledRayLength is 0, we still could have a hit with sphere casts (maybe?).
                // To avoid 0/0, set the fraction to 0.
                hitFraction = castHit ? (scaledRayLength > 0 ? rayHit.distance / scaledRayLength : 0.0f) : 1.0f;
                hitObject   = castHit ? rayHit.collider.gameObject : null;
            }
            else
            {
                RaycastHit2D rayHit;
                if (scaledCastRadius > 0f)
                {
                    rayHit = Physics2D.CircleCast(startPositionWorld, scaledCastRadius, rayDirection,
                                                  scaledRayLength, input.layerMask);
                }
                else
                {
                    rayHit = Physics2D.Raycast(startPositionWorld, rayDirection, scaledRayLength, input.layerMask);
                }

                castHit     = rayHit;
                hitFraction = castHit ? rayHit.fraction : 1.0f;
                hitObject   = castHit ? rayHit.collider.gameObject : null;
            }

            var rayOutput = new RayPerceptionOutput.RayOutput
            {
                hasHit          = castHit,
                hitFraction     = hitFraction,
                hitTaggedObject = false,
                hitTagIndex     = -1
            };

            if (castHit)
            {
                // Find the index of the tag of the object that was hit.
                for (var i = 0; i < input.detectableTags.Count; i++)
                {
                    if (hitObject.CompareTag(input.detectableTags[i]))
                    {
                        rayOutput.hitTaggedObject = true;
                        rayOutput.hitTagIndex     = i;
                        break;
                    }
                }
            }

            debugRayOut.worldStart = startPositionWorld;
            debugRayOut.worldEnd   = endPositionWorld;
            debugRayOut.rayOutput  = rayOutput;
            debugRayOut.castRadius = scaledCastRadius;

            return(rayOutput);
        }
 internal void SetRayPerceptionInput(RayPerceptionInput input)
 {
     // TODO make sure that number of rays and tags don't change
     m_RayPerceptionInput = input;
 }