Universal Robots+

FeatureModel method updateFeature throws an Uncatchable Exception: DefenseCheckException

Hello!

I use the FeatureModel method updateFeature in a daemon thread which starts in the constructor, but every now and then it throws a DefenseCheckException which is not caught in my try/catch.
I originally had it to run only in a non-looping thread, but then it tried to set the Feature before the installation was properly loaded, and it never really got set.
My code looks something like this:

private void setFeature(Pose pose) {
	Pose featurePose = null;
	try {
		featurePose = featureContributionModel.getFeature(FEATURE_NAME).getPose();
		System.out.println(featurePose.toString() + " and " + pose.toString());
	} catch (Exception e) {
		e.printStackTrace();
		featurePose = null;
	}
	if (pose == null) {
		if (featurePose == null) {
			return;
		}
		featureContributionModel.removeFeature(FEATURE_NAME);
		System.out.println("Removed feature: " + featurePose.toString());
		return;
	} else if (featurePose == null) {
		featureContributionModel.addFeature(FEATURE_NAME, FEATURE_NAME, pose);
		System.out.println("Added feature: " + pose.toString());
		return;
	} else if (!pose.epsilonEquals(featurePose, 0.00001, Length.Unit.MM, 0.00001, Angle.Unit.RAD)) {
		featureContributionModel.updateFeature(FEATURE_NAME, pose);
		System.out.println("Updated feature: " + pose.toString());
	}
}

private class MyThread extends Thread {
	private volatile boolean stop = false;
	public MyThread(){
		super(MY_THREAD_GROUP,"MyThread");
	}

	@Override
	public void run(){
		while (!stop) {
			// ... Bunch of other things
			try {
				Pose newFeaturePose = getFeaturePose();
				setFeature(newFeaturePose);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

Every now and then at start and even poweroff/restart, I get a printout of valid poses and then this unhandled exception, killing the thread (Even though I’m try/catch it):

12:36:32.847 ERROR - Caught an unhandled exception {thread: AWT-EventQueue-0 , loggerClass: gui.tools.URDialogCreator}
com.ur.lang.Defense$DefenseCheckException: Expect subject to NOT be null
        at com.ur.lang.Defense.notNull(Defense.java:33) ~[?:?]
        at com.ur.lang.Defense.notNull(Defense.java:28) ~[?:?]
        at com.ur.monitor.model.JointPositionVector.set(JointPositionVector.java:61) ~[?:?]
        at gui.program.position.LegacyPosition.set(LegacyPosition.java:79) ~[?:?]
        at gui.program.position.LegacyPosition.set(LegacyPosition.java:92) ~[?:?]
        at gui.polyscope.setup.treenodes.geom.GeomPoseNode.setSpatialPose(GeomPoseNode.java:278) ~[?:?]
        at com.ur.polyscope.geomfeature.urcaps.domain.feature.FeatureContributionModelImpl.doUpdateFeature_aroundBody8(FeatureContributionModelImpl.java:109) ~[?:?]
        at com.ur.polyscope.geomfeature.urcaps.domain.feature.FeatureContributionModelImpl$AjcClosure9.run(FeatureContributionModelImpl.java:1) ~[?:?]
        at org.aspectj.runtime.reflect.JoinPointImpl.proceed(JoinPointImpl.java:149) ~[?:?]
        at com.ur.polyscope.valueobjects.aspects.InterceptionUtils$1.proceed(InterceptionUtils.java:18) ~[?:?]
        at com.ur.polyscope.valueobjects.aspects.AbstractArgumentInterceptor.invoke(AbstractArgumentInterceptor.java:43) ~[?:?]
        at com.ur.polyscope.valueobjects.aspects.InterceptionUtils.intercept(InterceptionUtils.java:15) ~[?:?]
        at com.ur.polyscope.valueobjects.aspects.StringNotNullOrEmptyAspect.aroundAnnotatedMethod(StringNotNullOrEmptyAspect.java:18) ~[?:?]
        at com.ur.polyscope.geomfeature.urcaps.domain.feature.FeatureContributionModelImpl.doUpdateFeature_aroundBody10(FeatureContributionModelImpl.java:103) ~[?:?]
        at com.ur.polyscope.geomfeature.urcaps.domain.feature.FeatureContributionModelImpl$AjcClosure11.run(FeatureContributionModelImpl.java:1) ~[?:?]
        at org.aspectj.runtime.reflect.JoinPointImpl.proceed(JoinPointImpl.java:149) ~[?:?]
        at com.ur.polyscope.valueobjects.aspects.InterceptionUtils$1.proceed(InterceptionUtils.java:18) ~[?:?]
        at com.ur.polyscope.valueobjects.aspects.AbstractArgumentInterceptor.invoke(AbstractArgumentInterceptor.java:43) ~[?:?]
        at com.ur.polyscope.valueobjects.aspects.InterceptionUtils.intercept(InterceptionUtils.java:15) ~[?:?]
        at com.ur.polyscope.valueobjects.aspects.NotNullArgumentAspect.aroundAnnotatedMethod(NotNullArgumentAspect.java:18) ~[?:?]
        at com.ur.polyscope.geomfeature.urcaps.domain.feature.FeatureContributionModelImpl.doUpdateFeature(FeatureContributionModelImpl.java:103) ~[?:?]
        at com.ur.polyscope.geomfeature.urcaps.domain.feature.FeatureContributionModelImpl.updateFeature_aroundBody2(FeatureContributionModelImpl.java:82) ~[?:?]
        at com.ur.polyscope.geomfeature.urcaps.domain.feature.FeatureContributionModelImpl$AjcClosure3.run(FeatureContributionModelImpl.java:1) ~[?:?]
        at org.aspectj.runtime.reflect.JoinPointImpl.proceed(JoinPointImpl.java:149) ~[?:?]
        at com.ur.polyscope.valueobjects.aspects.UncaughtExceptionAspect.aroundMethod(UncaughtExceptionAspect.java:27) ~[?:?]
        at com.ur.polyscope.geomfeature.urcaps.domain.feature.FeatureContributionModelImpl.updateFeature(FeatureContributionModelImpl.java:80) ~[?:?]
        at com.Oviso.Ovi.impl.OviInstallationNodeContribution.setFeature(OviInstallationNodeContribution.java:1520) ~[?:?]
        at com.Oviso.Ovi.impl.OviInstallationNodeContribution.access$1600(OviInstallationNodeContribution.java:62) ~[?:?]
        at com.Oviso.Ovi.impl.OviInstallationNodeContribution$MyThread.run(OviInstallationNodeContribution.java:3522) ~[?:?]

So to problem solve I just removed the if statement for the update part so that it always tries to update continuously.

	} else {
	// if (!pose.epsilonEquals(featurePose, 0.01, Length.Unit.MM, 0.02, Angle.Unit.DEG)) {
		try{
			featureContributionModel.updateFeature(FEATURE_NAME, pose);
			System.out.println("Updated feature: " + pose.toString());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

Should get a FeatureNotFoundException in the catch if the feature instance has been changed since I did the get, since Pose for sure isn’t null, but I still get the same DefenseCheckException, only now I get it continously.
As I said, mostly it happens on power on and off.

Either way, workaround exists: Replace updateFeature with remove and add. Very ugly, but it’s the only way I could find that always works.

I have found the same exception and I have noticed that it is thrown when the pose could not be reached. I think the null subject in the description refers to the joint position vector which could not be generated.