I'm trying to use RoboDK and a Kuka with KRC4 controller for 3D printing and I'm hoping to control both the Robot and the Extruder through RoboDK using the "Run on Robot" function.
My idea is to have three very similar function calls "SetRPM", "Extruder" and "MCode". SetRPM giving the F Value, Extruder the E Value of the G1 commands and MCode all the M commands of the G Code. The functions would then use TCP/IP over Ethernet to send these values as text string to a controller board for the extruder before sending the corresponding move to the robot and then continuing with the program.
I'm hoping that this way the error between the moves and extrusions is limited to one move at a time and therefore very small to avoid either the robot or extruder running faster than the other. So far I have modified the post processor so it adds the lines SetRPM(ExtruderSpeed) and Extruder(PRINT_E_New) with the parameters in the brackets being the values for F and E. When I generate a program for the functions are being passed on to the robot program as you can see in the code example below at the end of the post.
My question is now, if I run this program through RoboDK on the robot can I use these lines to call functions or program events that will then send the corresponding code through a ethernet connection to the controlboard of the extruder? If so, do you know of any similar code snippets I could adapt the code from?
I have seen a lot of posts in the forum regarding 3D printing but none with this issue, is there perhaps a easier solution that I'm not aware of?
The post processor and the driver are different (having a working post processor does not mean the driver will work).
The best way to make this work with the driver is to trigger a program with a number. For example: Extruder(73) will pass the program id 73. However, this was designed to make it work for more simple calls (program ID). Example: Program 1 This will pass the program_id number 1. You can pass a floating point number (32 bit precision, more informationhere).
Note that it is not possible to trigger programs by name using this method. You are also limited to 1 value. We can improve it to pass 2 or 3 values if you need.
Once you pass the program id (as an integer or a decimal value) you need to implement your actions in the driver (SRC file). I attached the sample implementation code and comments in the driver file.
Code:
;----- Run program COM_VALUE1 --------- ;(to trigger from RoboDK: use robot.RunCodeCustom("program id", INSTRUCTION_CALL_PROGRAM) program_id = COM_VALUE1 SWITCH program_id CASE 1 ;-- run program 1 -- ;钻() ;------------------- CASE 2 ;-- run program 2 -- ;Cut() ;------------------- ENDSWITCH
thank you for the reply this actually helps a lot! I've been trying to modify the scripts in RDK and the Postprocessor when what I needed was the Robot driver. I looked in the directory where the drivers are and found that the kuka driver "apikuka" is a .exe file that i can't modify but there is a apikukaiiwa.py. From a quick look it seems that the driver is for a robot with 7 degrees of freedom, I'll try to get it working with our 6 DoF robot, but could you provide the apikuka.exe as .py file?
I would approach the problem by adding another elif like the one below:
Code:
elif n_cmd_values >= nDOFs_MIN and cmd_line.startswith("MOVL"): UpdateStatus(ROBOTCOM_WORKING) # Activate the monitor feedback ROBOT_MOVING = True # Execute a linear move. RoboDK provides j1,j2,...,j6,j7,x,y,z,w,p,r if ROBOT.SendCmd(MSG_MOVEL, cmd_values): # Wait for command to be executed if ROBOT.recv_acknowledge(): # Notify that we are done with this command UpdateStatus(ROBOTCOM_READY)
and change it so if the code starts with "Call Extruder" it establishes a connection by telnet to the extruder, sends the Gcode command and closes the connection.
After reading the second message I realized that you would like to communicate to the extruder using the computer (not the robot). Correct?
在这种情况下,集成和你可能会更容易can program the socket communication protocol using Python. Otherwise, you may need to purchase KUKA Ethernet/XML option to do so with a KUKA KRC controller.
To react on a program call (such as Extruder) in a custom way you can create an Extruder script like the one attached. You can collect arguments using sys.argv as shown here:
Code:
E_Value = None # Check if we are running this program inside another program and passing arguments import sys if len(sys.argv) > 1: E_Value = float(sys.argv[1])
Let me know if this is not what you are looking for.
Albert that's brilliant! It works! You saved my day :D
I just noticed the attached file when I went to post this, I went with Telnet instead but the segment to quit if in Simulation mode is neat, I'll add that and post some details on the scripts I end up using once I'm through testing in case someone else has the same issues.
I am also trying to implement extrusion via a python script in RoboDK for online programming of our Fanuc 6 axis robot. Did you come up with a solution after all? Myself, I was trying to use the Printrun library (from the Pronterface project) to send some G-code commands over to the extruder, but I can't make it work.
Could you share some details about the scripts that you developped? Any help would be highly appreciated.
If so, I recommend you to just send raw strings or binary data to update the extruder speed. You can implement your own protocol to just send the necessary information to the extruder.
Hi Albert. I am using an Arduino controler with the Marlin Firmware to drive the extruder. I would like to interpret the RoboDK's Extruder(x.xxx) function to send my own G-code to the Marlin Firmware.
(02-14-2020, 02:37 PM)JFCh Wrote:Hi Albert. I am using an Arduino controler with the Marlin Firmware to drive the extruder. I would like to interpret the RoboDK's Extruder(x.xxx) function to send my own G-code to the Marlin Firmware.
Hi JF,
sorry about not replying sooner. To be fair I was printing. My extruder is controlled by a duet2 so it can recieve gcode through http get requests. that makes it pretty straight forward. You can adapt the speed using a pre-processor to insert a function call after each robot speed change, then calling a funtion that works the same as the extruder call but transforms the mm/s from robodk to the mm/min in gcode and corrects for the crosssection of the extruded line compared to your filament crosssection. Below you'll find the code, you'll have to use the ip's of your respective boards.
Extruder
Code:
e_value = None from robolink import * #nur fuer Nutzung in RoboDK RDK = Robolink() # Check if we are running this program inside another program and passing arguments import sys if len(sys.argv) > 1: e_value = float(sys.argv[1]) code = 'G1 E' + str(e_value) #print(message) #for test purposes RDK.ShowMessage(code, popup=False) # for test purpose set to True for popup, set to false or comment out for use to avoid blocking if RDK.RunMode() == RUNMODE_SIMULATE: quit()
import requests params = {"gcode": code } r = requests.get("http://192.168.2.114/rr_status?type=1")
# print(r.json()) # for test purpose r = requests.get("http://192.168.2.114/rr_gcode", params=params) # this works! # r = requests.get("http://192.168.0.100/rr_gcode?gcode=G1 Z100") # this works! #print(r.json())
Speed
Code:
f_value = None from robolink import * #nur fuer Nutzung in RoboDK RDK = Robolink() # Check if we are running this program inside another program and passing arguments import sys if len(sys.argv) > 1: e_value = float(sys.argv[1]) f_transform = f_value * 60 * 1.5676 # mm / s毫米/分钟und adaptation for line crossection Q to fed filament Q/pi*(2.85/2)² code = 'G1 F' + str(f_transform) #print(message) #for test purposes RDK.ShowMessage(code, popup=False) # for test purpose set to True for popup, set to false or comment out for use to avoid blocking if RDK.RunMode() == RUNMODE_SIMULATE: quit()
import requests params = {"gcode": code } r = requests.get("http://192.168.2.114/rr_status?type=1")
#print(r.json()) # for test purpose r = requests.get("http://192.168.2.114/rr_gcode", params=params) # this works! # r = requests.get("http://192.168.0.100/rr_gcode?gcode=G1 Z100") # this also works! #print(r.json())
Pre-Processor:
Code:
from robolink import * # API to communicate with RoboDK from robodk import * # basic matrix operations RDK = Robolink()
# Ask the user to select a program: prog = RDK.ItemUserPick("Select a Program to modify", ITEM_TYPE_PROGRAM) if not prog.Valid(): 打印(“开放ration cancelled or no programs available") quit()
# Ask the user to enter a function call that will be added after each movement: print("Program selected: " + prog.Name()) ins_call = 'SetExtSpeed' #mbox("Enter a program call to add after each movement", entry="SynchRobot") if not ins_call: 打印(“开放ration cancelled") quit()
# Iterate through all the instructions in a program: ins_id = 0 ins_count = prog.InstructionCount() while ins_id < ins_count: # Retrieve instruction ins_nom, ins_type, move_type, isjointtarget, pose, joints = prog.Instruction(ins_id) if ins_type == INS_TYPE_CHANGESPEED: # Select the movement instruction as a reference prog.InstructionSelect(ins_id) value = prog.Instruction(ins_id) name = value[0] import re matches = re.findall("[+-]?\d+\.\d+", name)
# Add a new program call prog.RunInstruction(ins_call + '(' + matches[0] + ')', INSTRUCTION_CALL_PROGRAM)
# Advance one additional instruction as we just added another instruction ins_id = ins_id + 1 ins_count = ins_count + 1
It's been a while since I looked at the forum and I have missed your reply. Thank you very much for sharing the scripts with me. I will take a look and let you know the outcome.