I noticed that a paragraph of comment related to the method. I'm not sure whether method of your sunrise version has the same.
Posts by greengrape83
-
-
Your code snippet can't approach your purpose.
But you can do something like the following:Code
Display Morepublic void run() { lbr.move(lin(getApplicationData().getFrame("/A")).setCartVelocity(150)); // Collision condition ICondition collisionCondition = ForceCondition.createSpatialForceCondition(lbr.getFlange(), spatialForceLimit); // Collision observer ConditionObserver collisionObserver = getObserverManager().createAndEnableConditionObserver(collisionCondition, NotificationType.OnEnable, new IAnyEdgeListener()) { @Override public void onAnyEdge(ConditionObserver conditionObserver, Date time, int missedEvents, boolean conditionValue) { if (conditionValue) { // Here try to the sunrise execution service to cancel the motions and sunrise execution service can be retrieved from sunrise controller. SunriseExecutionService ses = null; ses = ... ses.cancelAll(); // After all the motions cancelled, execute your collision processing motion lbr.getCurrentCartesianPosition().move(linRel(0, 0, -100).setJointVelocityRel(0.3)); } else { // No collision so LBR can move again , so motion activated lbr.move(lin(getApplicationData().getFrame("/B")).setCartVelocity(150)); } } }); lbr.move(lin(getApplicationData().getFrame("/B")).setCartVelocity(150)); }
-
To avoid caring about the direction of the tool orientation and the additional control force.
I suggest that you teach your frames outside your metal container. And when the motion's target frame is outside the container shape, you should use impedance mode.
By defining target frame outside the shape together with impedance mode, you can ensure the tool is applied to the shape surface. -
Since you have the array of your frames, you can generate a spline like:
Code
Display MoreFrame[] yourFrames = null; //..... //Suppose you have filled your frame array SplineMotionCP<?>[] spMotions = new SplineMotionCP<?>[yourFrames.length]; for (int index = 0; index < yourFrames.length; index++) { spMotions[index] = spl(yourFrames[index]); } // Here comes the spline Spline sp = new Spline(spMotions); lbr.move(sp);
-
I haven't found a good solution to fix your issue.
But in some cases you can maintain motion containers and cancel the motion by container in the callback of you message receiving.
Or -
I think software condition is not the purpose of ICondition mechanism because the conditions provide the chance to monitor the robot/controller hardware status(Torque/Force/Joint position/IO and so on) and to make decisions(like 'breakwhen') directly at the real-time OS, rather than to cost a bit long time to go back to the rapi app layer to respond.
-
It is easy to simply realize the function that first collision to freeze, second to resume, third to freeze... by changing several code lines as following.
However, if the force wobble and user friendliness is considered, much more is needed to make a precise judgement when collision happens and when resume collision happens.Code
Display More// Some impedance mode may be necessary... //TODO: // Collision condition ICondition collisionCondition = ForceCondition.createSpatialForceCondition(lbr.getFlange(), 15.0d); // Collision observer // A class member to keep the state bCollision = true; ConditionObserver collisionObserver = getObserverManager().createAndEnableConditionObserver(collisionCondition, NotificationType.OnEnable, new IAnyEdgeListener() { @Override public void onAnyEdge(ConditionObserver conditionObserver, Date time, int missedEvents, boolean conditionValue) { if (conditionValue) { logger.info("force exceed"); // Here a collision or resume is detected and try to freeze/resume the robot if (bCollision) { logger.info("Collision"); getApplicationControl().setApplicationOverride(0.0d); } else { logger.info("resume"); getApplicationControl().setApplicationOverride(1.0d); } bCollision = !bCollision; } else { logger.info("force reduced"); // Some extra judgements may be necessary for force wobble when motion paused... // TODO // Here a collision is removed and try to unfreeze the robot //getApplicationControl().setApplicationOverride(1.0d); } } }); // A set of motions to go with the supposed the path. If collision detected, the current motion freezed. If collision removed, the motion continue. lbr.move(ptp(getApplicationData().getFrame("/P1"))); lbr.move(lin(getApplicationData().getFrame("/P2"))); lbr.move(circ(getApplicationData().getFrame("/P3"), getApplicationData().getFrame("/P4"))); lbr.move(ptp(getApplicationData().getFrame("/P5"))); // Disable and remove the observers. collisionObserver.disable(); getObserverManager().removeConditionObserver(collisionObserver);
-
Hi robotneuling,
I've tested the code snippet on my iiwa.
The robot motions are frozen when I press on the robot and the motions are resumed when I remove the press.
Maybe you can provide the task log about your app running for analysis. -
In the robot application you can call the following code lines to make your motions paused/half speed/resumed by different application override values.
-
-
If the z offset to sensorFrame is measured under the base of sensorFrame itself(the scenario in the attached image). You can get the new frame by the following codes.
-
The sunrise os manual specifies as the following, but I'm not sure it is the same scenario as yours.
"The following port numbers (client or server socket) can be used in a robot application:
30,000 to 30,010" -
The stop1 can stop the motor immediately and it is recoverable.
But I have never run into such programming interface to call it.
Still I suppose the ordinary motion stop is feasible for your app, because after the motion cancelled, the robot motion stops and robot won't move even if the motor isn't stopped immediately. -
There is a latency time of about 5 second between the motion stop/pause and the motor stop.
-
I've made some adjustment of the base frame generating function, which makes a as original point, x axis along with ab, under right hand law.
Also I made the calculated base frame child of world directly instead of child of frame a.Code
Display More/** * Generate a base frame from frame point a, b, c by right hand law. The base frame' z direction is the normal * direction of base abc, and x direction is same as ab. */ public static Frame generateBaseFrame(AbstractFrame a, AbstractFrame b, AbstractFrame c) { Vector startZ = Vector.of(0.0, 0.0, 1.0); Vector xVector = Vector.of(1.0, 0.0, 0.0); Vector direction = a.getOriginOf(b).toVector().crossProduct(a.getOriginOf(c).toVector()); if (direction.equals(Vector.of(0.0, 0.0, 0.0))) { throw new IllegalArgumentException("These 3 frames can't produce a base frame."); } double rotAngle = startZ.angleRad(direction); Vector rotAxis = null; if (rotAngle == 0.0 || rotAngle == Math.PI) { rotAxis = xVector; } else { rotAxis = startZ.crossProduct(direction); } Frame tmpZbase = new Frame(a, Transformation.of(Vector.of(0.0, 0.0, 0.0), AxisAngleRotation.of(rotAxis, rotAngle))); Vector abInbase = tmpZbase.getOriginOf(b).subtract(tmpZbase.getOriginOf(a)); double rotAngleInbase = xVector.angleRad(abInbase); if (rotAngleInbase == 0.0 || rotAngleInbase == Math.PI) { } else { if (xVector.crossProduct(abInbase).getZ() < 0.0d) { rotAngleInbase = -rotAngleInbase; } } return new Frame(tmpZbase.transform(Transformation.ofRad(0.0, 0.0, 0.0, rotAngleInbase, 0.0, 0.0)).transformationFromWorld()); }
-
Both bases are OK.
Firstly the x/y/z in the world are the same for the taught base and the calculated base.
Secondly the transformation between the two bases is [X=0.00 Y=0.00 Z=0.00 A=1.72 B=0.00 C=0.00] which means they have the same Z direction.If you want to specify the x,y direction of you base, you need to specify more(like x goes along ab direction) because the right hand law only can decide Z direction
CodeFrame a = new Frame(532.5, -160.7, -60.7, 0.2, -0.002, 3.1); Frame b = new Frame(532.5, -331.9, -60.7, 0.2, -0.002, 3.1); Frame c = new Frame(637.7, -160.6, -60.3, 0.2, -0.002, 3.1); Frame taughtBase = new Frame(532.5, -160.7, -60.7, -1.6, -0.001, 0.004); Frame calcBase = generateBaseFrame(a, b, c); System.out.println("calc base:" + calcBase.toStringInWorld()); System.out.println("base transform:" + taughtBase.staticTransformationTo(calcBase)); //calc base:[X=532.50 Y=-160.70 Z=-60.70 A=0.12 B=-0.00 C=-0.00] //base transform:[X=0.00 Y=0.00 Z=0.00 A=1.72 B=0.00 C=0.00]
-
I suspect that you have only printed the Transformation of the base frame relative to his parent(frame a).
You can get its transformation relative to World by method baseFrame.transformationFromWorld().
Also you can get the formula by the combination of cross multiplying and dot multiplying.
Maybe you can provide more details about your 3 frames/points so that I can have a verification. -
I'm afraid that the process data can only support java basic types(Integer/Double/Boolean/String).
But still you can convert your frame into a string of a specific format(like 'x,y,z,a,b,c') to save it into the process data. When you retrieve your frame from the process data, you have to parse the string.Another choice is to save your object frame into the application data source.
-
Actually you can directly add a frame on Smart Pad, if its version is not out-of-date.
-