# Crash when creating child nodes from and loading program - Custom API

**URL:** <https://forum.universal-robots.com/t/crash-when-creating-child-nodes-from-and-loading-program-custom-api/3463>\
**Category:** URCap Development\
**Tags:** welding\
**Created:** [January 15, 2019, 8:29pm UTC](https://forum.universal-robots.com/t/crash-when-creating-child-nodes-from-and-loading-program-custom-api/3463 "2019-01-15T20:29:17Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![anon44414354](https://avatars.discourse-cdn.com/v4/letter/a/a8b319/32.png) [@anon44414354](https://forum.universal-robots.com/u/anon44414354)\
**Post date:** [January 15, 2019, 8:29pm UTC](https://forum.universal-robots.com/t/crash-when-creating-child-nodes-from-and-loading-program-custom-api/3463/1 "2019-01-15T20:29:17Z")

</div>

Hello all,

I’m experiencing a couple of strange behaviors when implementing child program nodes from a parent one and when loading previously saved programs.  
What I want to implement is a parent program node, from which I can add or remove specific child nodes thanks to dedicated check boxes. The check box is selected, a specific child node is added; the check box is not selected, this child node is removed. Ideally, I would like to control where the child nodes are located in the hierarchy, preserving the coherence of the hierarchy when one specific child node is removed.  
I actually implemented this mechanism successfully but, as soon as I’m saving the program and loading it again, it crashes, showing me that I am developing it in a bad way.

**First test**  
I have developed a first URCap, implementing a parent program node including a child node, which is a standard “Wait” node. The parent program node includes 2 check boxes, which are in this test not doing much.

![image](https://us1.discourse-cdn.com/flex020/uploads/universal_robots/original/2X/3/30659dc8132bccab54ff7ef7e6b17ba61ee8f2e1.png)

The node hierarchy is created through the program node contribution:

```
TreeNode root = this.apiProvider.getProgramAPI().getProgramModel().getRootTreeNode(this);
WaitNode waitNode = this.programNodeFactory.createWaitNode();
Time oneSecondWait = this.programAPI.getValueFactoryProvider().getSimpleValueFactory().createTime(1, Time.Unit.S);
TimeWaitNodeConfig config = waitNode.getConfigFactory().createTimeConfig(oneSecondWait, ErrorHandler.AUTO_CORRECT);
this.programAPI.getProgramModel().getRootTreeNode(this).addChild(waitNode.setConfig(config));

```

When clicking on one of the check boxes, the data model is modified (within the context implemented by the UndoRedoManager) and the following line is executed (and only this one):

`TreeNode root = this.apiProvider.getProgramAPI().getProgramModel().getRootTreeNode(this);`  
When starting the program from scratch, no problem. When saving the program and loading it again, when interacting when one of the check boxes, a new “Wait” node appears. I don’t understand this behavior. How come this new node appears?

![image](https://us1.discourse-cdn.com/flex020/uploads/universal_robots/original/2X/1/1b459de542072beb14a384ad9c91c2a4eb56fe80.png)

Strangely enough, if I’m saving the program with one of the check boxes selected and loading it again, the check box is of course selected, and the additional node appears anyway if I am deselecting it. What is the reason behind that?

**Second test**  
In the second test, the child node A is a standard “Wait” node with a 2s duration and the child node B is a standard “Wait” node with a 3s duration. Taking into account the different samples, the node hierarchy is created within the constructor. When the user is clicking on one of the check boxes, the sub tree is cleared (i just copied/pasted the clearSubtree() method from the samples) and the function creating the hierarchy is executed again.

```
public void setAddChildAState(final boolean state)
{
  this.apiProvider.getProgramAPI().getUndoRedoManager().recordChanges(new UndoableChanges()
  {
    @Override
    public void executeChanges()
    {
      model.setAddChildAState(state);
      // clear subtree
      clearSubtree();
      // create sub tree again
      createSubtree();
    }
  });
}

```

The node hierarchy is created as in the first test, adding child nodes relatively to data model values.  
Here, no problem at all. I have the same behavior whether I am starting the program from scratch or I am loading a previously saved program. I’m clearing the whole sub-tree, not taking into account additional nodes eventually added by the user, but I guess I can solve that with a CustomAPI and the ProgramNodeVisitor.

**Third and last test**  
Now, instead of standard “Wait” nodes, I want to add nodes of my own. For the sake of testing from something, which is initially working, I actually added to my URCap the GripperOpenNode from the “Pick and Place” sample. It is the same code as before, but instead of initializing my node hierarchy with a standard “Wait” node, the one with the 1s duration, I am initializing it with the GripperOpenNode.

```
TreeNode root = this.apiProvider.getProgramAPI().getProgramModel().getRootTreeNode(this);

WaitNode waitNode2 = this.programNodeFactory.createWaitNode();
Time oneSecondWait2 = this.programAPI.getValueFactoryProvider().getSimpleValueFactory().createTime(2, Time.Unit.S);
TimeWaitNodeConfig config2 = waitNode2.getConfigFactory().createTimeConfig(oneSecondWait2, ErrorHandler.AUTO_CORRECT);

WaitNode waitNode3 = this.programNodeFactory.createWaitNode();
Time oneSecondWait3 = this.programAPI.getValueFactoryProvider().getSimpleValueFactory().createTime(3, Time.Unit.S);
TimeWaitNodeConfig config3 = waitNode3.getConfigFactory().createTimeConfig(oneSecondWait3, ErrorHandler.AUTO_CORRECT);

root.addChild(this.programNodeFactory.createURCapProgramNode(GripperOpenProgramNodeService.class));

if (this.model.getAddChildAState())
  this.programAPI.getProgramModel().getRootTreeNode(this).addChild(waitNode2.setConfig(config2));

if (this.model.getAddChildBState())
  this.programAPI.getProgramModel().getRootTreeNode(this).addChild(waitNode3.setConfig(config3));

```

Once again, starting the program from scratch, everything is going well. When loading the program and beginning to interact with the check boxes, a crash occurs. I don’t manage to know why it is happening. I tried to catch this exception without success for now.

 ![image](https://us1.discourse-cdn.com/flex020/uploads/universal_robots/original/2X/4/4952f3428c52afeb6b004a157e9917417b92f353.png)

If I’m saving the program with one of the check boxes selected, the program crashes as soon as I am clicking on the “Parent” node.  
1 remark here. If I’m executing the URCap from the first test, not implementing an initial “Wait” node with a 1s duration but with a GripperOpenNode, the same crash as the third test occurs.

I am of course developing it in a wrong way but where is the mistake? I tried as well to implement it thanks to TreeNodes and playing with the insertChildBefore() and insertChildAfter() methods - ideally, that’s how I would like to implement it - but the same bug occurs. I am working with the sdk 1.5.0. I don’t want to work with templates, as in the “Pick and place” sample, as the overall goal is to have more than 2 check boxes / child nodes. It will quickly be non-maintainable.

I implemented that the 3 tests as URCaps that can be compiled and installed, if anyone is interested to get the whole implementation.

[com.dti.test1.tar.gz](https://us1.discourse-cdn.com/flex020/uploads/universal_robots/original/2X/b/b25b03a2a58b35edb9e557d30760bb16de8ea41c.gz) (48.8 KB)  
[com.dti.test2.tar.gz](https://us1.discourse-cdn.com/flex020/uploads/universal_robots/original/2X/d/d734e9719336009ac30fcccab69698135e9786f4.gz) (48.8 KB)  
[com.dti.test3.tar.gz](https://us1.discourse-cdn.com/flex020/uploads/universal_robots/original/2X/4/465d5e7c2cb6d8a42162d24474c3cce69bf26d37.gz) (59.1 KB)

Any fresh ideas/fixes/new tests appreciated. Thank you very much in advance!

---

<div class="post-metadata">

**Author:** ![ajp](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.universal-robots.com/ajp/32/471_2.png) [@ajp](https://forum.universal-robots.com/u/ajp)\
**Post date:** [June 3, 2019, 5:47am UTC](https://forum.universal-robots.com/t/crash-when-creating-child-nodes-from-and-loading-program-custom-api/3463/2 "2019-06-03T05:47:37Z")

</div>

Hi @anon44414354, did you manage to resolve this issue/figure out what was going on?

---

<div class="post-metadata">

**Author:** ![anon44414354](https://avatars.discourse-cdn.com/v4/letter/a/a8b319/32.png) [@anon44414354](https://forum.universal-robots.com/u/anon44414354)\
**Post date:** [June 3, 2019, 9:33am UTC](https://forum.universal-robots.com/t/crash-when-creating-child-nodes-from-and-loading-program-custom-api/3463/3 "2019-06-03T09:33:39Z")

</div>

Hi @ajp  
Never receive an answer from it and was compelled to implement what I wanted in another way. The issue can be closed, even if it is not solved, if it is what you mean.

---

<div class="post-metadata">

**Author:** ![ajp](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.universal-robots.com/ajp/32/471_2.png) [@ajp](https://forum.universal-robots.com/u/ajp)\
**Post date:** [June 3, 2019, 9:54am UTC](https://forum.universal-robots.com/t/crash-when-creating-child-nodes-from-and-loading-program-custom-api/3463/4 "2019-06-03T09:54:25Z")

</div>

Hi @anon44414354, apologies that you didn’t get an answer from us. Someone else is experiencing the same issue, would you mind writing a few words about your alternative approach? Thanks.

---

<div class="post-metadata">

**Author:** ![anon44414354](https://avatars.discourse-cdn.com/v4/letter/a/a8b319/32.png) [@anon44414354](https://forum.universal-robots.com/u/anon44414354)\
**Post date:** [June 3, 2019, 1:30pm UTC](https://forum.universal-robots.com/t/crash-when-creating-child-nodes-from-and-loading-program-custom-api/3463/5 "2019-06-03T13:30:06Z")

</div>

Hi @ajp

What I implemented is the following:

- All the nodes I want to add or remove have a custom API interface, following the example from @jbm:  
[URCap Sample: URCap CustomAPI](https://forum.universal-robots.com/t/sample-urcap-customapi/3022)

**Node contribution:**

> public class MyNodeToAddAndRemoveContribution implements ProgramNodeContribution, MyNodeToAddAndRemoveCustomAPI  
> {  
> // this is my node contribution  
> }

**Node custom api interface:**

> public interface MyNodeToAddAndRemoveCustomAPI  
> {  
> // this is my custom api interface  
> // I have myself nothing inside this interface  
> }

- In my root node, from which I will be able thanks to a checkbox to add and remove the node mentioned previously:

1. I am using the ProgramNodeVisitor to retrieve the index of the MyNodeToAddAndRemove in my program hierarchy:

> private int getMyNodeToAddAndRemoveIndex()  
> {  
> final int childIndex = new int[1];  
> childIndex[0] = -1;
> 
> ```
> TreeNode root = apiProvider.getProgramAPI().getProgramModel().getRootTreeNode(this);
> 
> root.traverse(new ProgramNodeVisitor()
> {
> @Override
> public void visit(URCapProgramNode programNode, int index, int depth)
> {
> if(programNode.canGetAs(MyNodeToAddAndRemoveCustomAPI.class))
> {
> //System.out.println("Index: " + index);
> childIndex[0] = index;
> }
> }
> });
> 
> // return -1 if the node does not exist
> return childIndex[0];
> 
> ```
> 
> }

1. When the user enables or disables the check box:

> public void setMyNodeToAddAndRemoveState(final boolean state)  
> {  
> this.undoRedoManager.recordChanges(new UndoableChanges()  
> {  
> @Override  
> public void executeChanges()  
> {
> 
> ```
> // set the model state accordingly here
> // ...
> 
> TreeNode root = this.programAPI.getProgramModel().getRootTreeNode(this);
> 
> if (state)
> {
> // add the node (in try-catch)
> if (ProgramNodeHelper.getChildrenNb(root) > 0)
> root.insertChildBefore(root.getChildren().get(0), this.programNodeFactory.createURCapProgramNode(MyNodeToAddAndRemoveService.class));
> else
> root.addChild(this.programNodeFactory.createURCapProgramNode(MyNodeToAddAndRemoveService.class));
> }
> else
> {
> // remove the node (in try-catch)
> int myIndex = this.getMyNodeToAddAndRemoveIndex();
> if (myIndex < 0)
> return;
> root.removeChild(root.getChildren().get(myIndex));
> }
> }
> });
> 
> ```
> 
> }

1. If some sub nodes must be added anyway and are not interactable through checkboxes, they must be added from the root node constructor only if the context is a node creation:

> public MyRootNodeContribution(ProgramAPIProvider apiProvider, MyRootNodeView view,  
> DataModel model, CreationContext context)  
> {  
> // constructor  
> // do something  
> if (context.getNodeCreationType() == NodeCreationType.NEW)  
> {  
> TreeNode root = this.programAPI.getProgramModel().getRootTreeNode(this);  
> // in a try-catch  
> root.addChild(this.programNodeFactory.createURCapProgramNode(MyPermanentNodeService.class));  
> }  
> }

Sorry for the bad indentation. Other than that, that should do the trick. Let me know if you have any questions.

---

<div class="post-metadata">

**Author:** ![ajp](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.universal-robots.com/ajp/32/471_2.png) [@ajp](https://forum.universal-robots.com/u/ajp)\
**Post date:** [June 4, 2019, 3:21am UTC](https://forum.universal-robots.com/t/crash-when-creating-child-nodes-from-and-loading-program-custom-api/3463/6 "2019-06-04T03:21:49Z")

</div>

Thanks very much for that. @dmartin I heard you’re facing a similar issue, does this help you at all?

---

<div class="post-metadata">

**Author:** ![mmi](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.universal-robots.com/mmi/32/691_2.png) [@mmi](https://forum.universal-robots.com/u/mmi)\
**Post date:** [June 7, 2019, 10:59am UTC](https://forum.universal-robots.com/t/crash-when-creating-child-nodes-from-and-loading-program-custom-api/3463/7 "2019-06-07T10:59:19Z")

</div>

Issues with child nodes will be fixed in the next public release (after 5.4/3.10).  
Thank you for great description of the problem and examples, it helped a lot in finding out root cause.

---

<div class="post-metadata">

**Author:** ![anon63360713](https://avatars.discourse-cdn.com/v4/letter/a/ebca7d/32.png) [@anon63360713](https://forum.universal-robots.com/u/anon63360713)\
**Post date:** [June 25, 2019, 11:46am UTC](https://forum.universal-robots.com/t/crash-when-creating-child-nodes-from-and-loading-program-custom-api/3463/8 "2019-06-25T11:46:13Z")

</div>

A similar problem still occurs in URSim v5.4 / sdk 1.7.0.  
Is the problem fixed??

---

<div class="post-metadata">

**Author:** ![anon63360713](https://avatars.discourse-cdn.com/v4/letter/a/ebca7d/32.png) [@anon63360713](https://forum.universal-robots.com/u/anon63360713)\
**Post date:** [June 25, 2019, 12:11pm UTC](https://forum.universal-robots.com/t/crash-when-creating-child-nodes-from-and-loading-program-custom-api/3463/9 "2019-06-25T12:11:20Z")

</div>

In parent node constructor, I added child node and call child node api.

```
	try {
		root.addChild(programNodeFactory.createURCapProgramNode(ChildNodeService.class));
		setChildNodeAPI();
	} catch (TreeStructureException e) {
		e.printStackTrace();
	}

```

.

```
private void setIfNodeAPI() {
	final TreeNode root = apiProvider.getProgramAPI().getProgramModel().getRootTreeNode(this);
	
	root.traverse(new ProgramNodeVisitor() {
		public void visit(URCapProgramNode programNode, int index, int depth) {
			if(programNode.canGetAs(ChildNodeAPI.class)) {
				// call API function
			}
		}
	});
}

```

There is no problem when adding a parent node in URCaps.  
But when I save the program in .urp file and open it again, I get a problem.

When I added a parent node,

1. called parent node constructor -\> addChild function called
2. called child node constructor
3. called child node API

But when I open .urp file,

1. called parent node constructor -\> addChild function called
2. called child node API
3. called child node constructor

So… in setChildNodeAPI() function, I can’t get as (ChildNodeAPI.class)  
What can I do?

---

<div class="post-metadata">

**Author:** ![dmartin](https://avatars.discourse-cdn.com/v4/letter/d/c4cdca/32.png) [@dmartin](https://forum.universal-robots.com/u/dmartin)\
**Post date:** [June 25, 2019, 12:52pm UTC](https://forum.universal-robots.com/t/crash-when-creating-child-nodes-from-and-loading-program-custom-api/3463/10 "2019-06-25T12:52:44Z")

</div>

Hi @ajp! Hi @mmi! Hi @anon63360713!

Thank you all for your help. I was fighting with similar problems. So I put here my summary in case it help any of you.

I was given this two examples by the UR R&D Department:

```
  TreeNode tree = this.programAPI.getProgramModel().getRootTreeNode(this);
  final GripperMarkerInterface[] gripperContributionInterface = {null};
      tree.traverse(new ProgramNodeVisitor() {
        @Override
        public void visit(URCapProgramNode programNode, int index, int depth) {
          if(programNode.canGetAs(GripperMarkerInterface.class)) {
            GripperMarkerInterface urCapProgramNode = programNode.getAs(GripperMarkerInterface.class);
            gripperContributionInterface[0] = urCapProgramNode;
            System.err.println("ProgramNodeVisitor.visit: " + urCapProgramNode + ", title " + ((GripperOpenProgramNodeContribution) urCapProgramNode).getTitle());
          }
        }
      });
      tree.traverse(new URCapProgramNodeInterfaceVisitor<GripperMarkerInterface>() {
        @Override
        public void visitURCapAs(GripperMarkerInterface urCapProgramNode, int index, int depth) {
          gripperContributionInterface[0] = urCapProgramNode;
          System.err.println("URCapProgramNodeInterfaceVisitor.visitURCapAs: " + urCapProgramNode + ", title " + ((GripperOpenProgramNodeContribution)urCapProgramNode).getTitle());
        }
      });
      return gripperContributionInterface[0];

```

I ended up using the first approach, just because I was in a hurry (and involved in several different projects). So as the first was working to perfection, I didn’t test the second option.

Regarding the overall problem, and trying to summarize and close things.  
One of the difficulties was that I was having up to three different causes of problems, two of them closely related. This made even more difficult to know clearly what was the problem. The problems, solutions and comments are:

- **The need to _get root TreeNode every time_ I need to use it.**  
_ **Problem** _: I was getting my base root TreeNode just once in the class constructor. I thought it was a ‘static pointer’ all the time the program model is ‘alive’. I expected getting it just this once, I would see the children even if they were added afterwards.  
_ **Solution** _: Getting my root TreeNode **every time** I need it, using this three code lines:

- **The need to _manually manage initial children creation_, to create them just when the URCap node is new.**  
_ **Problem:** _ When a previously saved .urp is loaded, containing some of my URCap nodes, I was getting a variety of exceptions, mainly NullPointer exeptions, when trying to modify the inner structure of URCap. The nodes where shown in the program tree correctly, as they were saved. But trying to add/delete children nodes was always generation an exception.  
I quote an information from UR R&D Department: “When program is being loaded your constructor is called, and after it’s done all children are removed, and replaced with nodes loaded from urp file.” Well, I just confirmed this mechanism is not fully working, at least in my SDK simulator SW3.6.0.30512.  
_ **Solution attempts** _: While confirming if this is an API bug or not, and which versions are fixed, I tried a couple of ways:

- **Right usage of traverse, and how to use it with URCap nodes.**  
_ **Problem:** _ I couldn’t find enough examples for traverse usage, and none for using it for URCap nodes.  
_ **Solution:** _ Using your example code now I know how to use traverse. I also found this customAPI example that helped with the interface creation:

I’ve been polishing the code and I’m still running final tests. But so forth, it is working to perfection. So I hope it can help you too.  
And UR crew, please keep us up to date with your findings or solutions in this matter.

Thank you all!  
David Martin

---

<div class="post-metadata">

**Author:** ![Savoia](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.universal-robots.com/savoia/32/4844_2.png) [@Savoia](https://forum.universal-robots.com/u/Savoia)\
**Post date:** [January 19, 2021, 6:19pm UTC](https://forum.universal-robots.com/t/crash-when-creating-child-nodes-from-and-loading-program-custom-api/3463/11 "2021-01-19T18:19:23Z")

</div>

Closed on January 19, 2021, 6:19pm UTC


