void Awake()
    {
        string path = Application.dataPath + _packagePath;

        robot = CreateRobot(path, _fileName);

        bool    positive = _upAxis > 0;
        Axis    axis     = !positive ? (Axis)(-1 * (int)_upAxis) : _upAxis;
        Vector3 angles   = Vector3.zero;

        if (axis == Axis.POS_X)
        {
            angles.z = positive ? 90 : -90;
        }
        if (axis == Axis.POS_Z)
        {
            angles.x = positive ? 90 : -90;
        }
        if (axis == Axis.POS_Y)
        {
            angles.x = positive ? 0 : 180;
        }

        robot.transform.rotation = Quaternion.Euler(angles);
    }
    URDFJointList CreateRobot(string package, string urdf)
    {
        StreamReader  reader  = new StreamReader(package + urdf);
        string        content = reader.ReadToEnd();
        URDFJointList ujl     = URDFParser.BuildRobot(package, content);

        ujl.name = urdf;

        return(ujl);
    }
Exemple #3
0
    public override void OnInspectorGUI()
    {
        URDFJointList ujl = (URDFJointList)target;

        // Options
        EditorGUILayout.LabelField("Options", EditorStyles.boldLabel);
        _useDeg = EditorGUILayout.Toggle("Edit in Degrees", _useDeg);
        _sort   = EditorGUILayout.Toggle("Sort Alphabetically", _sort);
        _filter = EditorGUILayout.TextField("Filter", _filter);

        // Get the joints as a list so we can srot
        _list.Clear();
        _list.AddRange(ujl.joints.Keys);
        if (_sort)
        {
            _list.Sort();
        }

        // Joints
        EditorGUILayout.Space();
        EditorGUILayout.LabelField("Joints", EditorStyles.boldLabel);
        Regex re = new Regex(_filter, RegexOptions.ECMAScript | RegexOptions.IgnoreCase);

        foreach (string key in _list)
        {
            // If we don't match the regex, don't display this field
            if (_filter != "" && !re.IsMatch(key))
            {
                continue;
            }

            // Display the joint fields
            EditorGUI.BeginChangeCheck();
            float angle    = ujl.joints[key].angle * (_useDeg ? Mathf.Rad2Deg : 1);
            float newAngle = EditorGUILayout.FloatField(key, angle);
            if (EditorGUI.EndChangeCheck())
            {
                newAngle *= (_useDeg ? Mathf.Deg2Rad : 1);
                ujl.SetAngle(key, newAngle);
            }
        }
    }
Exemple #4
0
    // create the robot
    public static URDFJointList BuildRobot(string package, string urdfContent, System.Action <string, System.Action <Mesh[]> > loadMesh = null, URDFJointList urdfjointlist = null)
    {
        if (loadMesh == null)
        {
            loadMesh = LoadMesh;
        }

        // load the XML doc
        XmlDocument doc = new XmlDocument();

        doc.LoadXml(urdfContent);

        // Store the information about the link and the objects
        // indexed by link name
        Dictionary <string, XmlNode> xmlLinks  = new Dictionary <string, XmlNode>();
        Dictionary <string, XmlNode> xmlJoints = new Dictionary <string, XmlNode>();

        // indexed by joint name
        Dictionary <string, URDFJoint> urdfJoints = new Dictionary <string, URDFJoint>();
        Dictionary <string, URDFLink>  urdfLinks  = new Dictionary <string, URDFLink>();

        // first node is the robot node (for the full robot)
        foreach (XmlNode n in doc.ChildNodes)
        {
            // first node is expected to be the robot
            // cycle through and find all the links for the robot first
            foreach (XmlNode xLink in n.ChildNodes)
            {
                if (xLink.Name == "link")
                {
                    // Store the XML node for hte link
                    xmlLinks.Add(xLink.Attributes["name"].Value, xLink);

                    // create the link gameobject
                    URDFLink urdfLink = new URDFLink();
                    urdfLink.name      = xLink.Attributes["name"].Value;
                    urdfLink.transform = new GameObject(urdfLink.name).transform;
                    urdfLinks.Add(urdfLink.name, urdfLink);

                    // Get the geometry node and skip it if there isn't one
                    XmlNode[]       visualNodes = GetXmlNodeChildrenByName(xLink, "visual");
                    List <Renderer> renderers   = new List <Renderer>();

                    // Iterate over all the visual nodes
                    foreach (var vn in visualNodes)
                    {
                        XmlNode geomNode = GetXmlNodeChildByName(vn, "geometry");
                        if (geomNode == null)
                        {
                            continue;
                        }

                        XmlNode matNode = GetXmlNodeChildByName(vn, "material");
                        Color   col     = Color.white;
                        if (matNode != null)
                        {
                            XmlNode colNode = GetXmlNodeChildByName(matNode, "color");
                            if (colNode != null)
                            {
                                col = TupleToColor(colNode.Attributes["rgba"].Value);
                            }

                            // TODO: Load the textures
                            XmlNode texNode = GetXmlNodeChildByName(matNode, "texture");
                            if (texNode != null)
                            {
                            }
                        }

                        // Get the mesh and the origin nodes
                        // TODO: Handle boxes, spheres, and cylinders here
                        XmlNode meshNode      = GetXmlNodeChildByName(geomNode, "mesh");
                        XmlNode visOriginNode = GetXmlNodeChildByName(vn, "origin");

                        // take the visual origin and place on the renderer
                        // use the visual origin to set the pose if necessary
                        Vector3 visPos = Vector3.zero;
                        if (visOriginNode != null && visOriginNode.Attributes["xyz"] != null)
                        {
                            visPos = TupleToVector3(visOriginNode.Attributes["xyz"].Value);
                        }
                        visPos = URDFToUnityPos(visPos);

                        Vector3 visRot = Vector3.zero;
                        if (visOriginNode != null && visOriginNode.Attributes["rpy"] != null)
                        {
                            visRot = TupleToVector3(visOriginNode.Attributes["rpy"].Value);
                        }
                        visRot = URDFToUnityRot(visRot);

                        // load the STL file if possible
                        try {
                            // get the file path and split it
                            string fileName = meshNode.Attributes["filename"].Value;
                            fileName = Path.Combine(package, fileName.Replace("package://", ""));

                            // load all meshes
                            loadMesh(fileName, meshes => {
                                if (meshes.Length > 0)
                                {
                                    // create the rest of the meshes and child them to the click target
                                    for (int i = 0; i < meshes.Length; i++)
                                    {
                                        Renderer r = GameObject.CreatePrimitive(PrimitiveType.Cube).GetComponent <Renderer>();
                                        r.GetComponent <MeshFilter>().mesh = meshes[i];

                                        r.transform.parent        = urdfLink.transform;
                                        r.transform.localPosition = visPos;
                                        r.transform.localRotation = Quaternion.Euler(visRot);

                                        r.name           = urdfLink.name + " geometry " + i;
                                        r.material.color = col;

                                        renderers.Add(r);

                                        Destroy(r.GetComponent <Collider>());
                                        Destroy(r.GetComponent <Rigidbody>());
                                    }
                                }
                            });

                            // save the geometry in the link
                            urdfLink.geometry = renderers;
                        } catch (System.Exception e) {
                            Debug.LogError("Error loading model for " + urdfLink.name + " : " + e.Message);
                        }
                    }
                }
            }

            // find all the joints next
            foreach (XmlNode xJoint in n.ChildNodes)
            {
                if (xJoint.Name == "joint")
                {
                    string jointName = xJoint.Attributes["name"].Value;

                    // store the joints indexed by child name so we can find it later
                    // to properly indicate the parents in the joint list
                    xmlJoints.Add(jointName, xJoint);

                    // Get the links by name
                    URDFLink parentLink = urdfLinks[GetXmlNodeChildByName(xJoint, "parent").Attributes["link"].Value];
                    URDFLink childLink  = urdfLinks[GetXmlNodeChildByName(xJoint, "child").Attributes["link"].Value];

                    // Create the joint
                    URDFJoint urdfJoint = new URDFJoint();
                    urdfJoint.name       = jointName;
                    urdfJoint.parentLink = parentLink;
                    urdfJoint.transform  = new GameObject(urdfJoint.name).transform;
                    urdfJoint.type       = xJoint.Attributes["type"].Value;

                    // set the tree hierarchy
                    // Parent the joint to its parent link
                    urdfJoint.parentLink       = parentLink;
                    urdfJoint.transform.parent = parentLink.transform;
                    parentLink.children.Add(urdfJoint);

                    // Parent the child link to this joint
                    urdfJoint.childLink        = childLink;
                    childLink.transform.parent = urdfJoint.transform;
                    childLink.parent           = urdfJoint;

                    childLink.transform.localPosition = Vector3.zero;
                    childLink.transform.localRotation = Quaternion.identity;

                    // position the origin if it's specified
                    XmlNode transNode = GetXmlNodeChildByName(xJoint, "origin");
                    Vector3 pos       = Vector3.zero;
                    if (transNode != null && transNode.Attributes["xyz"] != null)
                    {
                        pos = TupleToVector3(transNode.Attributes["xyz"].Value);
                    }
                    pos = URDFToUnityPos(pos);

                    Vector3 rot = Vector3.zero;
                    if (transNode != null && transNode.Attributes["rpy"] != null)
                    {
                        rot = TupleToVector3(transNode.Attributes["rpy"].Value);
                    }
                    rot = URDFToUnityRot(rot);

                    // parent the joint and name it
                    urdfJoint.transform.localPosition = pos;
                    urdfJoint.transform.localRotation = Quaternion.Euler(rot);
                    urdfJoint.originalRotation        = urdfJoint.transform.localRotation;

                    XmlNode axisNode = GetXmlNodeChildByName(xJoint, "axis");
                    if (axisNode != null)
                    {
                        Vector3 axis = TupleToVector3(axisNode.Attributes["xyz"].Value);
                        axis.Normalize();
                        axis           = URDFToUnityPos(axis);
                        urdfJoint.axis = axis;
                    }

                    XmlNode limitNode = GetXmlNodeChildByName(xJoint, "limit");
                    if (limitNode != null)
                    {
                        if (limitNode.Attributes["lower"] != null)
                        {
                            urdfJoint.minAngle = float.Parse(limitNode.Attributes["lower"].Value);
                        }
                        if (limitNode.Attributes["upper"] != null)
                        {
                            urdfJoint.maxAngle = float.Parse(limitNode.Attributes["upper"].Value);
                        }
                    }

                    // save the URDF joint
                    urdfJoints.Add(urdfJoint.name, urdfJoint);
                }
            }
        }

        // loop through all the transforms until we find the one that has no parent
        foreach (KeyValuePair <string, URDFLink> kv in urdfLinks)
        {
            // TODO : if there are multiple robots described, then we'll only be getting
            // the one. Should update to return a list of jointlists if necessary
            if (kv.Value.parent == null)
            {
                // find the top most node and add a joint list to it
                if (urdfjointlist == null)
                {
                    urdfjointlist = kv.Value.transform.gameObject.AddComponent <URDFJointList>();
                }
                else
                {
                    kv.Value.transform.parent        = urdfjointlist.transform;
                    kv.Value.transform.localPosition = Vector3.zero;
                    kv.Value.transform.localRotation = Quaternion.identity;
                }
                urdfjointlist.links  = urdfLinks;
                urdfjointlist.joints = urdfJoints;

                urdfjointlist.IsConsistent();
                return(urdfjointlist);
            }
        }
        return(null);
    }
Exemple #5
0
    // Load the URDF from file and build the robot
    public static URDFJointList LoadURDFRobot(string package, string urdfpath, System.Action <string, System.Action <Mesh[]> > loadMesh = null, URDFJointList urdfjointlist = null)
    {
        string       path    = Path.Combine(package, urdfpath);
        StreamReader reader  = new StreamReader(path);
        string       content = reader.ReadToEnd();

        return(BuildRobot(package, content, loadMesh, urdfjointlist));
    }