Unity-Technologies / URDF-Importer

URDF importer
Apache License 2.0
217 stars 71 forks source link

Getting index out of bound error after importing urdf of robot model in my unity scene #137

Closed Akashleena closed 2 years ago

Akashleena commented 3 years ago

IndexOutOfRangeException: Index was outside the bounds of the array. Unity.Robotics.UrdfImporter.Control.Controller.StoreJointColors (System.Int32 index) (at Library/PackageCache/com.unity.robotics.urdf-importer@e9859c4bec/Runtime/Controller/Controller.cs:163) Unity.Robotics.UrdfImporter.Control.Controller.Start () (at [Library/PackageCache/com.unity.robotics.urdf-importer@e9859c4bec/Runtime/Controller/Controller.cs:49)]

My controller.cs file is as follows: using System; using Unity.Robotics; using UnityEngine;

namespace Unity.Robotics.UrdfImporter.Control { public enum RotationDirection { None = 0, Positive = 1, Negative = -1 }; public enum ControlType { PositionControl };

public class Controller : MonoBehaviour
{
    private ArticulationBody[] articulationChain;
    // Stores original colors of the part being highlighted
    private Color[] prevColor;
    private int previousIndex;

    [InspectorReadOnly(hideInEditMode: true)]
    public string selectedJoint;
    [HideInInspector]
    public int selectedIndex;

    public ControlType control = ControlType.PositionControl;
    public float stiffness;
    public float damping;
    public float forceLimit;
    public float speed = 5f; // Units: degree/s
    public float torque = 100f; // Units: Nm or N
    public float acceleration = 5f;// Units: m/s^2 / degree/s^2

    [Tooltip("Color to highlight the currently selected join")]
    public Color highLightColor = new Color(1.0f, 0, 0, 1.0f);

    void Start()
    {
        previousIndex = selectedIndex = 1;
        this.gameObject.AddComponent<FKRobot>();
        articulationChain = this.GetComponentsInChildren<ArticulationBody>();
        int defDyanmicVal = 10;
        foreach (ArticulationBody joint in articulationChain)
        {
            joint.gameObject.AddComponent<JointControl>();
            joint.jointFriction = defDyanmicVal;
            joint.angularDamping = defDyanmicVal;
            ArticulationDrive currentDrive = joint.xDrive;
            currentDrive.forceLimit = forceLimit;
            joint.xDrive = currentDrive;
        }
        DisplaySelectedJoint(selectedIndex);
        StoreJointColors(selectedIndex);
    }

    void SetSelectedJointIndex(int index)
    {
        if (articulationChain.Length > 0) 
        {
            selectedIndex = (index + articulationChain.Length) % articulationChain.Length;
        }
    }

    void Update()
    {
        bool SelectionInput1 = Input.GetKeyDown("right");
        bool SelectionInput2 = Input.GetKeyDown("left");

        SetSelectedJointIndex(selectedIndex); // to make sure it is in the valid range
        UpdateDirection(selectedIndex);

        if (SelectionInput2)
        {
            SetSelectedJointIndex(selectedIndex - 1);
            Highlight(selectedIndex);
        }
        else if (SelectionInput1)
        {
            SetSelectedJointIndex(selectedIndex + 1);
            Highlight(selectedIndex);
        }

        UpdateDirection(selectedIndex);
    }

    /// <summary>
    /// Highlights the color of the robot by changing the color of the part to a color set by the user in the inspector window
    /// </summary>
    /// <param name="selectedIndex">Index of the link selected in the Articulation Chain</param>
    private void Highlight(int selectedIndex)
    {
        if (selectedIndex == previousIndex || selectedIndex < 0 || selectedIndex >= articulationChain.Length) 
        {
            return;
        }

        // reset colors for the previously selected joint
        ResetJointColors(previousIndex);

        // store colors for the current selected joint
        StoreJointColors(selectedIndex);

        DisplaySelectedJoint(selectedIndex);
        Renderer[] rendererList = articulationChain[selectedIndex].transform.GetChild(0).GetComponentsInChildren<Renderer>();

        // set the color of the selected join meshes to the highlight color
        foreach (var mesh in rendererList)
        {
            MaterialExtensions.SetMaterialColor(mesh.material, highLightColor);
        }
    }

    void DisplaySelectedJoint(int selectedIndex)
    {
        if (selectedIndex < 0 || selectedIndex >= articulationChain.Length) 
        {
            return;
        }
        selectedJoint = articulationChain[selectedIndex].name + " (" + selectedIndex + ")";
    }

    /// <summary>
    /// Sets the direction of movement of the joint on every update
    /// </summary>
    /// <param name="jointIndex">Index of the link selected in the Articulation Chain</param>
    private void UpdateDirection(int jointIndex)
    {
        if (jointIndex < 0 || jointIndex >= articulationChain.Length) 
        {
            return;
        }

        float moveDirection = Input.GetAxis("Vertical");
        JointControl current = articulationChain[jointIndex].GetComponent<JointControl>();
        if (previousIndex != jointIndex)
        {
            JointControl previous = articulationChain[previousIndex].GetComponent<JointControl>();
            previous.direction = RotationDirection.None;
            previousIndex = jointIndex;
        }

        if (current.controltype != control) 
        {
            UpdateControlType(current);
        }

        if (moveDirection > 0)
        {
            current.direction = RotationDirection.Positive;
        }
        else if (moveDirection < 0)
        {
            current.direction = RotationDirection.Negative;
        }
        else
        {
            current.direction = RotationDirection.None;
        }
    }

    /// <summary>
    /// Stores original color of the part being highlighted
    /// </summary>
    /// <param name="index">Index of the part in the Articulation chain</param>
    private void StoreJointColors(int index)
    {
        Renderer[] materialLists = articulationChain[index].transform.GetChild(0).GetComponentsInChildren<Renderer>();
        prevColor = new Color[materialLists.Length];
        for (int counter = 0; counter < materialLists.Length; counter++)
        {
            prevColor[counter] = MaterialExtensions.GetMaterialColor(materialLists[counter]);
        }
    }

    /// <summary>
    /// Resets original color of the part being highlighted
    /// </summary>
    /// <param name="index">Index of the part in the Articulation chain</param>
    private void ResetJointColors(int index)
    {
        Renderer[] previousRendererList = articulationChain[index].transform.GetChild(0).GetComponentsInChildren<Renderer>();
        for (int counter = 0; counter < previousRendererList.Length; counter++)
        {
            MaterialExtensions.SetMaterialColor(previousRendererList[counter].material, prevColor[counter]);
        }
    }

    public void UpdateControlType(JointControl joint)
    {
        joint.controltype = control;
        if (control == ControlType.PositionControl)
        {
            ArticulationDrive drive = joint.joint.xDrive;
            drive.stiffness = stiffness;
            drive.damping = damping;
            joint.joint.xDrive = drive;
        }
    }

    public void OnGUI()
    {
        GUIStyle centeredStyle = GUI.skin.GetStyle("Label");
        centeredStyle.alignment = TextAnchor.UpperCenter;
        GUI.Label(new Rect(Screen.width / 2 - 200, 10, 400, 20), "Press left/right arrow keys to select a robot joint.", centeredStyle);
        GUI.Label(new Rect(Screen.width / 2 - 200, 30, 400, 20), "Press up/down arrow keys to move " + selectedJoint + ".", centeredStyle);
    }
}
at669 commented 3 years ago

Hi, thanks for the report! Could you provide more details about this issue, including (where possible):

Could you also describe what happens exactly when you import the robot? Is it successfully importing the full robot without any other errors before you get this IndexOutOfRangeException? My initial suspicion is that the articulationChain (articulationChain = this.GetComponentsInChildren<ArticulationBody>();) is not populating correctly due to the full robot not importing as expected.

[Ticket# AIRO-1125]

github-actions[bot] commented 2 years ago

This issue has been marked stale because it has been open for 14 days with no activity. Please remove the stale label or comment on this issue, or the issue will be automatically closed in the next 14 days.

github-actions[bot] commented 2 years ago

This issue has been marked stale for 14 days and will now be closed. If this issue is still valid, please ping a maintainer.