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