Visual Components' Community

New Thinking for Factory Simulation
Welcome to Visual Components' Community Sign in | Help
in Search

Robotics: How to test for robot collisions using the COM interface

Last post to, marras 6 2008 14:31 by stabi. 0 replies.
Page 1 of 1 (1 items)
Sort Posts: Previous Next
  • to, marras 6 2008 14:31

    • stabi
    • Top 10 Contributor
    • Joined on pe, helmi 22 2008
    • Helsinki, Finland
    • Posts 32

    Robotics: How to test for robot collisions using the COM interface

    Abstract

    This article explains how to test for collisions between a robot and its surrounding parts using the COM interface.

    Overview

    Collision testing in 3DCreate is implemented in the collision detector layout item, or collision detector. The collision detector contains two node lists, and these lists contain the simulation nodes that are tested for collisions when one of the test functions is called. Collision testing uses the current state of the components in the simulation to see if any of the geometry in the listed nodes collide.

    Reachability and motion interpolation calculation, on the other hand, is done using robot calculation objects, which work independently of the simulation state of the robot. This means that you need to transfer the calculation results to the robot model in the simulation before calling any collision testing functions. To do this, you obtain a motion tester object from the robot. This object contains a single COM property, CurrentTarget, which reflects the current position of the robot. Setting this target changes the position of the robot.

    The following example code is written in C#, and is based on the robot layout shown in the picture below: 


    The layout can be downloaded here.

    Creating the collision detector

    The collision detector is created using the createLayoutItem() method, which is defined in the IvcApplication2 interface.

    Note: The createCollisionDetector() method defined in IvcApplication is deprecated since 3DCreate version 3.1. The recommended way to create collision detector objects is to use the createLayoutItem() method in IvcApplication2.

    The following code example shows how:

    // This assumes that the following is defined and initialized
    // IvcApplication vcApp;
    // The application object also implements IvcApplication2, but it needs to be explicitly cast.
    // Note that IvcApplication2 extends IvcApplication, so one alternative to the explicit cast below
    // is to define vcApp as an IvcApplication2 instance.
    IvcApplication2 app2 = (IvcApplication2)vcApp;

    // The collision detector is a layout item of type "CollisionDetector".
    // The IvcPropertyList returned by createLayoutItem() must explicitly be cast to
    // IvcCollisionDetector.
    IvcCollisionDetector detector = (IvcCollisionDetector)app2.createLayoutItem("CollisionDetector");

    Using the collision detector

    The collision detector contains 2 node lists that specify the parts of the layout to test for collisions. Each list is accessible as an IvcNodeList instance. This interface defines methods for creating and deleting entries in the list. Each entry is accessible as an IvcNodeEntry instance, and contains the following information:

    • Node: This is an IvcNode reference that can be any simulation node in the layout.
    • Type: This is a numerical value that determines how the entry is processed:
      • 0: The specified node or nodes are included in the list.
      • 1: The specified node or nodes are excluded from the list.
    • Scope: This is a numerical value that determines the scope of the entry:
      • 0: Node. Only the specified node is affected.
      • 1: Component. The specified node, and all its child nodes in the same component are affected.
      • 2: Tree. The specified node, and all its child nodes, including child components, are affected.

    The collision detector obtains the final node list by evaluating each entry, and adding and removing nodes as specified, in the order that the entries appear in the list. This is done every time a collision testing function is called; this way, changes in the component hierarchy (such as when a robot grasps or releases an item, or when a part moves from one conveyor to another) are properly handled.  

    The following code example sets up the previously created collision detector to test for collisions between the robot and the gripper on one hand, and between any other component on the other:

    // The collision detector has two lists, ListA and ListB. 
    // Add the robot and any attachments to ListA. This requires only one entry.

    // First, get the robot component.
    IvcComponent robotComponent = vcApp.findComponent("Robot");
    IvcNodeEntry entry = detector.ListA.createEntry();

    // The node is specified as a COM property that needs to be set by reference.
    IvcNode robotRootNode = robotComponent.RootNode;

    entry.set_Node(ref robotRootNode);
    // The other properties are dynamic properties, and set using setProperty().
    entry.setProperty("Type", 0); // Include.
    entry.setProperty("Scope", 2) // Tree. This also includes any attached grippers.

    // Specify ListB to include all components except the robot and its attachments.
    // This requires two entries.
    // The first entry includes the world root node, and all its child nodes.
    // The second entry excludes the robot root node, and all its child nodes.
    // Note that the order of the entries is important. Each new entry is added to
    // the end of the node list.

    // Create the first entry.
    entry = detector.ListB.createEntry();
    IvcNode worldRootNode = vcApp.RootNode;
    entry.set_Node(ref worldRootNode);

    entry.setProperty("Type", 0); // Include
    entry.setProperty("Scope", 2); // Tree. This includes all the nodes in the simulation.

    // Create the second entry
    entry = detector.ListB.createEntry();
    entry.set_Node(ref robotRootNode);
    entry.setProperty("Type", 1); // Exclude. This removes nodes from the nodes included so far.
    entry.setProperty("Scope", 2); // Tree. This excludes the robot and any attached components.

    After this, the collision detector can be used to test for collisions between the robot and any surrounding parts. IvcCollisionDetector defines two methods for testing collisions:

    • testOneCollision(). This method returns after finding the first collision, and returns a collision information object. If no collision is found, it returns null.
    • testAllCollisions(). This method keeps testing after finding a collision, and returns an array of all collision information objects.

    Both methods accept a tolerance parameter, which is the spatial tolerance, in millimeters, that is applied to the collision test. The returned collision information object is an instance of IvcCollisionInfo, and contains the following information:

    • NodeA, NodeB: The simulation nodes associated with the collision.
    • FeatureA, FeatureB: The feature nodes that generated the colliding geometry.
    • GeometrySetA, GeometrySetB: The geometry sets that collided.

    The following is an example of how to test whether or not there is a collision:

    IvcCollisionInfo info = detector.testOneCollision(0.0);

    if(info != null)
    {
    // collision detected
    }
    else
    {
    // no collision
    }

    Moving the robot

    In order to move the robot, a motion tester object can be obtained through the getMotionTester() method in the IvcRobot interface. Only one motion tester object can be used simultaneously for each robot. After use, the tester needs to be released by calling its destroy() method. This ensures that getMotionTester() succeeds the next time it is called. Otherwise, due to garbage collection the robot may not be released immediately, causing another call to getMotionTester() to fail.

    This example shows how to use the motion tester, using the example layout:

    // Get the robot component.
    IvcComponent robotComponent = vcApp.findComponent("Robot");

    // Get the robot controller.
    IvcRobot robot = (IvcRobot)vcApp.findBehaviour("KRC");

    // Note: Only one tester can be active for each robot. If the tester is already used by some
    // other COM client, getMotionTester() will raise an error.
    IvcMotionTester tester;

    try
    {
    tester = robot.getMotionTester();
    }
    catch(System.Runtime.InteropServices.COMException e)
    {
    // motion tester is already in use
    tester = null;
    }

    if(tester != null)
    {
    // Create a motion interpolator and add some points.
    IvcMotionTarget target = robot.createTarget();
    IvcMotionInterpolator interpolator = robot.createMotionInterpolator();

    // Add starting point.
    interpolator.addTarget(ref target);

    // This will cause the gripper to hit the table.
    target.TargetMatrix = new double[ ] {1000,0,1000,0,180,0};
    interpolator.addTarget(ref target);

    // Interpolate the motion and test if the robot collides.
    double cycleTime = interpolator.getCycleTimeAtTarget(1);

    for(double t = 0.0; t <= cycleTime; t += 0.0625)
    {
    interpolator.interpolate(t, ref target);
    tester.set_CurrentTarget(ref target);
    IvcCollisionInfo info = detector.testOneCollision(0.0);

    if(info != null)
    {
    // Display a message box showing which components collided.
    MessageBox.Show(
    string.Format(
    "{0} collided with {1} at time {2}.",
    info.NodeA.Component.getProperty("Name"),
    info.NodeB.Component.getProperty("Name"),
    t
    )
    );

    break;
    }
    }

    // Release the tester after use.
    // This is to ensure that the next call to getMotionTester() succeeds.
    // The tester object cannot be used again after this.
    tester.destroy();
    }
    Filed under: , , ,
Page 1 of 1 (1 items)