10-23-2021, 02:43 PM (This post was last modified: 10-23-2021, 02:57 PM by Hofbauec.)
I am currently working on a bed leveling system for a robotic 3D-printing station during the course of my master degree. I have already implemented every function necessary to level the actual print bed (creating probe points on irregular print surface, creating a mesh, interpolation of mesh, applying new z-values to G-Code). Therefore I used a button which calls a function with specific parameters declared above the button in the UI.
The last thing i need to implement seems to be quite a problem for my understanding of RoboDK. I need to move the robot down to the print bed (no problem) and as soon as a sensor sends a signal (via serial, input already works), the movement of the robot should stop and the next point should be probed.
I already tried to move the robot only a little bit at a time and check if the sensor is actve afterwards, but the main problem that prevents this implementation is, that the function which is called from the button only applies the motion, when the function is complete / ended. But i need to do a lot of probe points in this function inside a loop. I can't find a solution to move the robot without ending the function itself.
I am using ->runProgram(); where a lot of MoveL commands are implemented. But as I said, the actual "runProgram" only occurs at the end of the button call.
Is there a possibility to force the Robot to move inside of a button-function before the function reaches its end?
I hope someone can help me with my problem.
I am using the PluginExample as a base for my plugin (C++).
I assume your sensor works like a touch probe. I recommend you to run the search algorithm on a script, even if your goal is to create a plugin. You can trigger a Python scripts behind the scenes and collect the result. A script is better as you'll have less function callbacks and you can execute your robot program linearly (which is not so easy to do on a plugin as you can't execute blocking robot movements).
I attached some code that shows how to run a binary search algorithm using Python code. The search is done by steps of 1 mm and when a contact is found it starts splitting the search by half until you meet a certain tolerance.
We also have a search function (SearchL) in the RoboDK API which you can run from a Python script. On the other hand, this search algorithm requires additional configuration steps on the robot controller.
def PoseTowards(pose1, pose2, dist1_mm):
"""Return the pose that is delta_mm far from pose1 towards pose2"""
if dist1_mm <= 0:
# out of bounds/invalid
dist1_mm = 0
pose_delta = invH(pose1) * pose2
distance = norm3(pose_delta.Pos())
if dist1_mm > distance:
# out of bounds
dist1_mm = distance
def ProbePoint(xyzijk, r, poseref=eye(4)):
"""Probe a point using the preferred probing method"""
return ProbePointSteps(xyzijk, r, poseref)
return ProbePointBinary(xyzijk, r, poseref)
def ProbePointBinary(pose_from, pose_to, r, search_step_max=1):
"""Probe one point using a binary search algorithm and return the joints with the collision point. Returns None if no collision was found.
pose_from: From pose
pose_to: To pose
r: robot item
# Stabilization time in seconds
PAUSE_MOVE = 0.25
# Digital input for the probe
DI_PROBE = 0
# Set to 1 for DI ON when probe activated or 0 otherwise
PROBE_ON = 1
# Minimum increment to make a robot move (make it half the repeatability of a robot)
MIN_INCREMENT = 0.005
# Define the first increment, shift_z contains the offset with respect to the start point towards the second point
shift_z = search_step
itcount = 0
itcount_same = 0 # counter with the same direction
shift_z_last = None
contact = None
contact_last = None
sense_last = None
# Make sure the new point is within accepted boundaries
shift_z = min(max(shift_z, 0), pose_distance)
# Calculate the new pose to move to
pose_shift_z = PoseTowards(pose_from, pose_to, shift_z)
# Move the robot to the new position
# This should raise an exception if the robot had issues
#Verify that the movement was possible
#status, status_msg = robot.ConnectedState()
#if status != ROBOTCOM_READY:
# # Stop if the connection did not succeed
# printLog("Move not possible for real robot")
# Force delay to have more stable data!!
# Get the probe input
contact_str = r.getDI(DI_PROBE)
contact = str(PROBE_ON) in contact_str
# Detect the sense of motion
sense = 1.0 if contact else -1.0
if sense != sense_last:
# reset counter for movements in the same direction
itcount_same = 0
# Detect the end of the iteration:
print("%02i-Plane Z= %5.3f mm %s Step= %.3f" % (itcount, shift_z, u'\u2191' if sense > 0 else u'\u2193', delta_move_abs))
if contact and not contact_last and shift_z_last is not None and delta_move_abs < 4*TOLERANCE_MM: # shift_z_last-T.shift_z < S.TOLERANCE_MM:
# Termination criteria, we are done, we detected a valid point
targetJoints = r.Joints().list()
10-25-2021, 04:15 PM (This post was last modified: 10-25-2021, 04:16 PM by Hofbauec.)
I already imlemented this method in my program. Thank you very much you saved my day it works perfectly.
Is there a method to jump to the next instruction in a already running program in RoboDK via python? That would make my application failsafe proof. (I have put a picture of what I want to achive in the attachement)