IComponentContainer EventHandler for detaching component

Hi everyone,

I am trying to configure an adaptable collision detector, which changes a gripped part from collision group a to b, and vice versa when it is released by a robot. Here you can see a part of my code I use. The first event handler ChangeCollisionDetectorAttach works, however, it is called twice every time. I added a loop to unsubscribe from the event multiple times, but it doesn’t do its part. The other event handler will not be called no matter what I do.

`
// Initialize event handlers for collision detectors
foreach (ISimComponent cmp in robotsAndTools)

        // get componentcontainer behavior of robot
        IComponentContainer componentContainer = (IComponentContainer)cmp.GetBehavior(BehaviorType.ComponentContainer);
        if(componentContainer == null)
        {
            componentContainer = (IComponentContainer)cmp.FindBehavior("GraspContainer");
            if (componentContainer == null)
            {
                var behaviors = cmp.Behaviors;
                foreach (var behaviour in behaviors)
                {
                    if (behaviour.Name.Contains("GraspContainer"))
                    {
                        componentContainer = (IComponentContainer)cmp.FindBehavior(behaviour.Name);
                    }
                }
            }
        }
        if (componentContainer != null)
        {
            // Unsubscribe from event first to prevent multiple calls => 
            for (int i = 0; i < 15; i++)
            {
                componentContainer.ComponentLeaving -= ChangeCollisionDetectorDetach;
                componentContainer.ComponentArriving -= ChangeCollisionDetectorAttach;
                app.Simulation.SimulationReset -= ResetCollisionDetector;
            }
            componentContainer.ComponentArriving += ChangeCollisionDetectorAttach; // => gets called twice
            componentContainer.ComponentLeaving += ChangeCollisionDetectorDetach; // no calls :( 
        }
    }
    app.Simulation.SimulationReset += ResetCollisionDetector; // works properly
    
    /// <summary>
    /// Called, when a component is grasped by a robot
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    public static void ChangeCollisionDetectorAttach(object sender, ContainerTransitionEventArgs e)       // wird aufgerufen, 2 aber nicht
    {
        IApplication app = IoC.Get<IApplication>();
        IMessageService ms = IoC.Get<IMessageService>();
        IComponentContainer graspContainer = (IComponentContainer)sender;
        IDetectorManager detectorManager = IoC.Get<IDetectorManager>();
        List<ICollisionDetector> detectors = detectorManager.AllDetectors;
        ISimComponent cmpTail = graspContainer.TailComponent;
        ICollisionDetector detector = detectors.Find(x => x.Name.Equals(graspContainer.Node.Component));
        if (detector == null)
        {
            detector = detectors.Find(x => x.Name.Equals(graspContainer.Node.Parent.Parent.Component.Name));
        }

        if (detector != null)
        {
            var ListA = detector.NodeListA;
            List<ISimComponent> tools;
            IReadOnlyCollection<ISimComponent> components = app.World.Components;
            List<NodeListEntry> nodeListEntryA = new List<NodeListEntry>();
            List<NodeListEntry> nodeListEntryB = new List<NodeListEntry>();

            tools = UsefulCodeSnippets.GetTools();
            tools.Add(UsefulCodeSnippets.GetRobot(detector.Name).Component);
            //other = Find_Components();

            foreach (ISimComponent cmp in tools)
            {
                foreach (ISimNode node in cmp.Nodes)
                {
                    // exclude mountplate and first node of robot from detector
                    if (!(node.Name == detector.Name || node.Name == "Link6" || node.Name == "mountplate" || node.Name == "A6"))
                    {
                        NodeListEntry entry = new NodeListEntry(node, NodeEntryScope.Node, NodeEntryType.Include);
                        nodeListEntryA.Add(entry);
                    }
                    else
                    {
                        NodeListEntry entry = new NodeListEntry(node, NodeEntryScope.Node, NodeEntryType.Exclude);
                        nodeListEntryA.Add(entry);
                    }
                }
            }

            foreach (ISimComponent cmp in components)
            {
                ISimComponent test = tools.Find(x => x.Name.Equals(cmp.Name));
                if(test == null)
                {
                    ISimNode rnode = cmp.RootNode;
                    if (cmp.Name != cmpTail.Name)
                    {
                        NodeListEntry entry = new NodeListEntry(rnode, NodeEntryScope.Component, NodeEntryType.Include);
                        nodeListEntryB.Add(entry);
                    }
                    else
                    {
                        NodeListEntry entry = new NodeListEntry(rnode, NodeEntryScope.Component, NodeEntryType.Include);
                        nodeListEntryA.Add(entry);
                    }
                }
            }

            detector.SetNodeListA(nodeListEntryA);
            detector.SetNodeListB(nodeListEntryB);
        }
    }

`

I tried it as python script as well. There, I have the same issue. I can get an event handler for grasping a component, but the handler is not called when the component is released from the vcComponentContainer:

from vcScript import *
counter = 1
tool = getComponent()
print tool.Name
componentContainer = tool.findBehaviour("GraspContainer_2F-85_TCP")
print componentContainer.Name

def CounterHochzaehlen():
  global counter
  print counter
  counter = counter + 1

def myTest(arg, arg2):
  print "Call works!"
  print arg.Name
  print arg2
  CounterHochzaehlen()
  
componentContainer.OnTransition = myTest # Triggered when a component is transferred to or from the container. => Nope, only when a component transferred to the container 

def OnSignal( signal ):
  pass

def OnRun():
  pass

Coming to my questions:

  • Is this a reasonable approach for my idea?
  • Are there any issues related to these event handler known?

Cheers
Joshua

Hy,

what happens if you call the IDetectorManager.ReConfigureDetectors() after you changes?

Regards
Feature

Hi captain_feature,

thank you for your idea. But I am not quite sure how this helps to solve the issue with calling the event handlers for IComponentContainer. When the robot grasps a component, the detector is updatet. However, the other event handler for releasing a component from the componen container ist not called no matter what I do.
Nonetheless, I added your line of code both to the first method for initialization of the event handlers as well as into the first method that is called during grasping. However, it did not make a difference. The output is still the same.

Regards
Joshua


ComponentContainer Properties

I think I am one step closer to the problem: The components released by the gripper are still listed in the gripper’s componentContainer. Of course, the event handler is not called if the components never left it.

So my question now is:
Why are they still in the componentContainer even though I have released them with robot signals?

I have attached an image of the robot and its configuration for grabbing and releasing components. It consists of a UR5 with a Robotiq 2F-85 gripper in external mode. I am using signal port 1 for gripping and releasing and 101/102 for visualizing the finger movements of the gripper.

Any help is much appreciated :slight_smile:

Regards
Joshua

Hy,

do the component move with the robot after releasing?

What is the signal 101 and 102 for when you grab and release it with 1?

Regards
Feature

No, components are released. They stay, where the robot leaves them. At the same time, they don’t leave the componentContainer (that is the tricky part and why I didn’t find the issue earlier). 101 and 102 actually do nothing (my bad). They were connected to the gripper to open and close the fingers, but I changed the control of the gripper to external. So now the J1 value is stored within the statements.
I deleted the unecessary signal output statements, the result is still the same.

Hy,

sounds not logical for me…

You could have a look into the pythonScript of the robot, where grab/release actually take part, for better understand how VC handles this?

Regards
Feature

Hi feature,

I solved my problem: The property “releaseToWorld” in the robots ActionSignals properties was not set. After checking the box, the components are now released from the component container.

To summarize it: Setting the action signal (in action config, image botton part) to zero places the component, but does not release it from the component container of the robot/gripper. For that, you have to select the property additionally. Then you can you the action event of the component container.

Thank you for your help :slight_smile:

Regards
Joshua

Hy

I thought about something like this, but you mentioned that the part not moves with the robot after release…

If not release to world I believe that VC search for the nearest componentContainer which in your case is the same as before…

You’re welcome. :slight_smile:

Regards
Feature