Costum movenode

hello,

Can anyone tell me how to create a MoveP / MoveJ node with my own layout? Or tips that help me on my way. I can’t find it in any of the examples.

Greetings Zoë

Zoe,

UR+ portail is full of tutorials and examples on how to create your own URCap nodes. I would suggest you start looking at the section ‘My Fisrt URCap’ here. There are many example I am sure will help you get started !

Julien

Hi @jsthilaire ,

Thank you for your response

I know how to make a normal program node but i ran into the fact that a move node works a little differently. Meanwhile I have started to look at it from a different angle and I don’t think it needs to be very different from another node.

However, I am now stuck that the following code doesn’t seem to retrieve the position of the robot that I need for my waypoint

UserInterfaceAPI uiapi = apiProvider.getUserInterfaceAPI();
uiapi.getUserInteraction().getUserDefinedRobotPosition(new RobotPositionCallback2() {
@Override
public void onOk(PositionParameters positionParameters) {
model.set(POSITION_WAYPOINT, positionParameters.getPose());
System.out.println(positionParameters.getPose());
}

		public void onCancel(){
		
		}

Any ideas on how to fix this?

regards, Zoe

Zoe,

everytime you are saving data to the data model you must use the undoRedoManager in order for that value to be persistent.

Try this :

final UndoRedoManager undoRedoManager = apiProvider.getProgramAPI().getUndoRedoManager();

apiProvider.getUserInterfaceAPI().getUserInteraction().getUserDefinedRobotPosition(new RobotPositionCallback2() {
					@Override
					public void onOk(final PositionParameters parameters) {
						undoRedoManager.recordChanges(new UndoableChanges() {
							@Override
							public void executeChanges() {
                               model.set(POSITION_WAYPOINT, parameters.getPose());
                            }
                         }
                     }

                 });

to query the data, the undoRedoManager is not required :

Pose userPose = model.get(POSITION_WAYPOINT, null)

@jsthilaire

If i use this code, i get the following message…

@jsthilaire
I found the mistake. It was in making the variable. Thank you so much for your help!

One thing I’ll point out so you don’t make the same mistake I did. If you are capturing only the Pose with “parameters.getPose()” and decide to allow the user to select Joint Move later on (like in a future update) you’ll need to be able to pass it a Joint Positions. This will be incompatible with existing programs whose waypoints were created before capturing the Joint Positions.

To really mimic a built-in UR move, you may want to also just capture and store the Joint Positions so they are there if you need them. Of course, if you’re just doing a MoveP type move, then they can only be linear anyway. Just a thought.

@eric.feldmann good point, we also usually save all 3 PositionParameters outputs to the data model :

parameters.getPose()
parameters.getJointPositions()
parameters.getTCPOffset()

@eric.feldmann @jsthilaire

Thank you guys for the great advice, I will take it with me by creating the moveNode.

I actually had one more question, do you guys happen to know if it is possible to make a dropdown menu with java swing with the features?

kind regards,
Zoë Hermans

Yes you can do this.

The view:

public void setFeatureSelectionItems(final Feature[] items) {
	featureSelectionBox.removeAllItems();
	featureSelectionBox.setModel(new DefaultComboBoxModel<>(items));
}

The contribution function that generates the input parameter to the above view function:

private Feature[] getFeatures() {
		final Filter<Feature> filter = element -> {
			if (element.getClass().equals(FeaturePlane.class)) {
				return false;
			} else {
				if (!element.isDefined()) {
					return false;
				} else if (!element.isResolvable()) {
					return false;
				}
			}

			return true;
		};

		final Collection<Feature> features = new ArrayList<>();
		features.add(programAPI.getFeatureModel().getBaseFeature());
		features.addAll(programAPI.getFeatureModel().getGeomFeatures(filter));

		return features.toArray(new Feature[0]);
	}

Just be warned, when using the Features, you have to make sure that all your custom moves now check which Feature is active and convert all your saved poses/joint positions to that frame. I’ve spent many many hours troubleshooting issues resulting from moves not behaving correctly when selecting a Feature.

@eric.feldmann

i was thinking about converting the waypoints the way you said here:

Thankyou so much for helping me and thinking with me.

kind regards

Hi @eric.feldmann,

I am trying to use the features from the combobox now, but it constanly says that my base is not defined if i select the baseFeature. it also doensn’t want to be the default selected item… i tried getPose, setSelectedIndex, and tried to fill in the kind of arraylist. But this also doesn’t seem to work. The rest of the features are working perfectly.

Do you know the solution maybe?

Hmm not sure about why it would be undefined as long as you’re using the built-in programAPI.getFeatureModel().getBaseFeature() to capture it. This is what I’m doing in the “getFeatures()” function in the above reply.

As for having it selected to Base by default, I use this:

public void setFeatureSelected(final Feature item) {
		featureSelectionBox.setSelectedItem(item);
	}

And I pass it the Feature that I’m storing as the Active Feature in my datamodel. I do this because I allow the user to select a Default Feature if they want, so any moves they add automatically come in with THAT feature instead. Like this:

public Feature getDefaultFeature() {
		return model.get(Position.ACTIVE_FEATURE, apiProvider.getInstallationAPI().getFeatureModel().getBaseFeature());
	}

So if they haven’t set a Feature themselves, the model.get() will return the Base Feature by default.