I am trying to implement a template program node consisting of three move nodes and a user defined action. It is very close to the URCap-VisionTemplate provided by @jbm which I use as reference to get started on the whole template topic.
What I’m trying to achieve additionally is:
Let the user set/select an ID in the root node
Right before each move node: make an XMLRPCall using the ID from the root node that returns the target pose for the next waypoint
Root Node --> user sets an target ID in the view
XMLRPCall --> get_entry_pose(ID)
MoveJ
entry_pose
XMLRPCall --> get_target_pose(ID)
MoveL
target_pose
<User defined action>
XMLRPCall --> get_exit_pose(ID)
MoveL
exit_pose
My Current Approach:
Have dedicated program nodes that perform the XMLRPCalls. This way I was able to arrange the XMLRPCalls in between the other child nodes.
Downsides:
Lots of boilerplate code for the program nodes that perform only a single XMLRPCall
The extra program nodes make the template look long and complex
The program nodes could be added on their own to a robot program as they show up in the regular set of program nodes
Somehow the target ID entered in the root node has to be passed on the child nodes. I don’t know how to do this yet
Questions
What’s the idiomatic way to achieve this behavior?
Is is possible achieve this in a way that the user does not see XMLRPCalls in the robot program?
In case you trust that the entry-, target- and exit-poses does not change while the template is executing, you could query all poses in the parent (root) node, and store the results in variables for the variable Waypoints of entry, target and exit.
Something like;
Root Node // Sets ID, queries all XMLRPC poses on entry
- MoveJ
-- entry_pose // variable waypoint, set in Root Node
- MoveL
-- target_pose // variable waypoint, set in Root Node
- User Actions // Folder, or Gripper nodes etc. like shown in the references sample.
-- <empty>
- MoveL
-- exit_pose // variable waypoint, set in Root Node
There is some background to having the XMLRPCalls in between the move nodes (I probably should have stated that in the original post but I wanted to keep it simple).
The XMLRPCalls are intended to serve the following additional purposes:
Inform the daemon process that the previous waypoint has been reached
Block the robot program until the daemon process has finished evaluating external sensor data and answered the call
So in summary the calls are used to keep the robot program and a state machine in the daemon process in sync.
Then you are likely required to have the nodes in the tree, to enable the XML-RPC triggers between the waypoints.
The concern from a UX perspective I totally follow, and if it becomes to negative on the user experience side, I’d consider changing the state machine logic for a one-time fire.
To make the nodes unavailable to be added manually, you need to set the “UserInsertable” flag to false in the Service registration for the node.
To set the target ID to the child nodes, you should take a look at the “Custom API”. There is a sample here:
On the matter of boilerplate-reduction;
You can make an abstract implementation of the “XMLRPC Program Node Contribution”.
I assume the GUI and functionality of each node will be very much the same, so an alternative is to create an abstract class, which is extended by thin implementations that only care about the XML-RPC call, the node title and other small things that change - you could even set these in the constructor. For the View, you could re-use the same implementation and setup the differences from the Contribution. You can then do 3 Service registrations, calling the extending version of your Program Node Contributions.
Since changing the state machine logic is not an option at the moment the nodes probably have to stay in the tree. But maybe I can make a virtue out of necessity and make the communication taking place as transparent as possible to the user.
[…] you need to set the “UserInsertable” flag to false
Awesome! That’s what I was looking for.
[…] take a look at the “Custom API”
Pefekt, will do
You can make an abstract implementation of the “XMLRPC Program Node Contribution”
Makes perfect sense
Thank you for the help. I will go and try this out. No further questions atm