Posts by ColoradoTaco
-
-
H.CHOI it is a LOT easier to add characters to a text string than to parse them out of an existing string.
You can do it like this in your IF statement
IF currentjob=JobName+".job" THEN
For comparison, here is the vision load routine I run. It checks the existing job first, and only loads if the requested job is different.
Code
Display MorePROC LoadVisionJob(string JobName) VAR string currentjob; currentjob:=CamGetLoadedJob(Cognex_8402); TPWrite "Current Cam Job: "+currentjob; IF currentjob=JobName+".job" THEN TPWrite "Current Job matches Requested Job."; RETURN ; ELSE CamFlush Cognex_8402; CamSetProgramMode Cognex_8402; TPWrite "Camera set to Program Mode"; CamLoadJob Cognex_8402,JobName; TPWrite "Loaded Camera Job: "+JobName; CamSetRunMode Cognex_8402; TPWrite "Camera set to Run Mode"; ENDIF RETURN ; ENDPROC
-
I'm curious to see if you are either dropping or retaining the job name suffix. Also, the GetCamLoadedJob can take a second to process. Sometimes it helps to add just a tiny delay to allow registers to get updated.
Try this after your GetCamLoadedJob instruction:
If those two lines don't print out exactly the same on the pendant, you'll have your answer.
-
The CamGetLoadedJob function can leave the .job suffix in the string it returns. This will make the <> comparison not match. For example, the string "camjob" does not match a string of "camjob.job". For testing, you can use a TPWrite instruction to show each of the two variables before during testing and make sure the strings are in the same format.
I discovered the exact same thing recently. Here's the routine I'm running in a no-stepin.
H.CHOI Notice that the string pulled by CamGetLoadedJob does NOT include the .job suffix. I add that to the comparative IF statement to check if the requested job matches.
Code
Display MorePROC LoadVisionJob(string JobName) VAR string currentjob; currentjob:=CamGetLoadedJob(Cognex_8402); TPWrite "Current Cam Job: "+currentjob; IF currentjob=JobName+".job" THEN TPWrite "Current Job matches Requested Job."; RETURN ; ELSE CamFlush Cognex_8402; CamSetProgramMode Cognex_8402; TPWrite "Camera set to Program Mode"; CamLoadJob Cognex_8402,JobName; TPWrite "Loaded Camera Job: "+JobName; CamSetRunMode Cognex_8402; TPWrite "Camera set to Run Mode"; ENDIF RETURN ; ENDPROC
-
3. Switching safe tools by using a non-safe cross connection is not safe. You should normally use inputs from a safety rated source (e.g. a F-PLC) to activate safety functions.
Yeah, best practice would certainly agree with that. Unfortunately, no safety PLC here. I think that my cross-connect might just be too fast for the safety system, so I'm activating one tool before the other is deactivated in SafeMove. Never tried it, but is there a way to set up a delayed cross-connect, or should I just hard code it in a non-motion routine?
Also, is there a way other than a PLC to make that cross connect "Safe"?
-
-
-
I told them that was the only answer and we made it work. I'm not sure why my plc guy didn't want a GO but that's what we're using.
This is the way.
-
Are you connected via EtherNet to the PLC? If so, you should be able to send data that way via socket messaging and just transmit the speedrefresh value.
Buy why was the GO solution shot down? Because it's definitely the correct-est answer.
-
Your robtargets are tied to WobjSTN1. That means that as your positioner (STN1) moves, the robot will reorient to stay with it.
Do you have coordinated motion established? It's been awhile since I dealt with positioners, but if you want the robot to move independently of the station or vice versa, you will need to turn coordinated motion OFF. (Or do a MoveAbsJ and only modify the positioner values, but that can get weird)
-
H.CHOI okay, I see a couple of issues from what you were able to share...
It looks like you are using a single camera (mounted to the robot arm) to perform two separate inspections. This is why it was programmed to load a different job each time, and that is what is killing your cycle time. It is normal for CamLoadJob to take a good 5-10 seconds to complete.
If you can find a way to consolidate your vision jobs into a single job that can handle either case, this will eliminate that issue entirely.
Alternately, if you know whether your next image will be LH or RH ahead of time, then you can load the correct camera job early, so that you're not waiting for it once you are in position to capture the image.
Something else you can do is look at the job that is currently loaded, and only load a new job if needed. (My syntax might be off here, but this is about what it would be)
-
H.CHOI are you loading the cam job for every image? It only needs to be loaded once. After that, it's just CamReqImage each time you want a picture.
If you can provide details on your process we might be able to help you streamline it more.
-
Jleon89 , good practice for any jointtarget that isn't interfacing with some other part or fixture is to round numbers off so they're easy to read and quickly know if something is off. I typically stick to 5* increments.
e.g. JHome := [[-90,0,60,0,30,0],[9E+09,9E+09,9E+09,9E+09,9E+09,9E+09]];
-
I just set up a trap similar to what you suggested, and it seems to work but with a few bugs.
1. it finished the routine it was running before going home. is there any way to make it either finish the movement it's on then jump to the trap or stop in its tracks (preferably this way) and immediately start the trap routine.
The way that interrupts work, it will never be truly "instantaneous." Once the interrupt is triggered, whatever instruction is currently being performed must finish first. For instance, if you are in the middle of a long move that will take 5 seconds to complete, the Trap routine will not start until that move instruction is complete.
Quote from Jleon892. I want it, after running the trap, to end the module so the operator has to start from the beginning. is the "exitcycle" command at the end of the trap the correct way to do this?
Yes, ExitCycle is exactly what you want there. Don't forget though, depending on the rest of your program, you may need to reset and/or validate some variables or signals after an ExitCycle. Otherwise, it may result in unexpected system function.
Quote from Jleon893. when trying to run the program a second time i got an instruction error telling me it's not legal to connect a variable to a trap more than once. is there something i need to add to reset that at the end of the module? how do I address that?
As Alex H commented, you will need to utilize IDelete (and possibly ISleep / IWatch, depending on how you set things up).
The connection between Interrupt and Trap can only be made once. And other interrupts can occur while inside a trap routine. So there are several instructions to help control these situations...
- IDelete - removes the relationship between a Trap and interrupt. Will require the use of CONNECT instruction to restore. IDelete should be used on startup to wipe the slate, then re-define and connect your Interrupts and Traps.
- IDisable - Temporarily blocks ALL interrupts. Used if you want to ensure that none of your other Interrupts trigger during a certain event. Reverse this command with IEnable.
- ISleep - Deactivates an individual interrupt. Reverse this command with IWatch.
-
If you need to do something like repeatedly offset your WorkObject while stacking boxes or 3D printing, you will want to look at the POSE data type.
From the RAPID Instructions, Functions, and Data Types manual...
QuoteVAR pose frame1;
...
frame1.trans := [50, 0, 40];
frame1.rot := [1, 0, 0, 0];
The frame1 coordinate transformation is assigned a value that corresponds to a
displacement in position, where X=50 mm, Y=0 mm, Z=40 mm; there is, however,
no rotation. -
i do not have a homing program set to trigger at start up just a program to set a worldzone for the home position. usually when we go motors on the signal will pop up but not always. and sometimes motors off will turn it off even if its sitting at home. if i jog the robot out of then back to its home the output will turn on and if i jog out of home it turns off like it should but for some reason will be on most of the time when running the main program in auto. no matter where the robot is the robot at home bit is on. the customer does not want the operators to have to touch the TP at power up so i need it to see that its home without having to jog the robot.
If you are having trouble getting the world zone to trigger before any major movements, you can create a short routine which captures the current position, then moves a few degrees or millimeters then returns to the original position. This should be sufficient to trigger the WorldZone, which I'm quite sure requires motion to activate/deactivate.
-
Whichever method you use to get the current position, I find that using MoveOffs and MoveRelTool are extremely useful for extracting from a tight location.
What I like to do for complex homing routines is do a series of tests for robot position (cartesian and axis positions), tool position (grippers open/closed/etc.) and set a numerical value for each IF-THEN. No motion here, you are just establishing position and conditions. That allows you to really focus on every possible scenario you might have to get HOME from.
Once you have all your scenarios made up, and setting the value of your Escape Condition variable, write a TEST/CASE statement containing the specific motions required for each.
This method can get a little lengthy, but I find that it helps me account for every foreseeable scenario, and keep the conditions separate from the motion.
... Be sure to test your homing routine a LOT before putting it in service. Nothing worse than thinking you've got it and then you run MoveToHome from an unforeseen position and destroy a fixture or some tooling.
-
- Declare your interrupt
- Connect you INT to a TRAP
- Tie a timer or signal to your interrupt
- In your TRAP routine, write your homing instructions
In the example below, when the digital input goes high, the TRAP routine will be called immediately after the completion of any current instruction on the stack. Once the TRAP is complete, execution will return to the previous stack level.
Code
Display MoreVAR intnum INTERRUPTUS_MAXIMUS TRAP tr_VENGEANCE TPWrite "My name is Maximus Decimus Meridius."; RETURN ; ENDTRAP PROC main() CONNECT INTERRUPTUS_MAXIMUS WITH trVENGEANCE ISignalDI di_TellMeYourName,1,INTERRUPTUS_MAXIMUS; IEnable; !Production Stuff ENDPROC
There is a lot more that CAN be done, but this is the basic structure.
-
If you want to be able to call the homing routine at anytime (I presume with an input signal) then you are looking for Traps & Interrupts. You will need both.
The interrupt, once established, allows the robot to constantly monitor for a specific input signal (or other condition, such as a timer reaching a certain value). Once the interrupt is triggered, it will call a TRAP routine, which can perform essentially any task, including motion. After the trap routine is completed, it will return to the previous execution stack unless otherwise directed.
They can be a little tricky the first time, but there are lots of details and examples in the documentation. You will need to reference:
TRM - RAPID Instructions, Functions, and Data types
TRM - RAPID Kernel
TRM - RAPID Overview
-
I have an OmniCore controller attached to a CRB-1100 (SWIFTI). Trying to set up SafeMove tools and having a Tool Change error.
Setup:
- I have one pneumatic gripper which is mounted to a 90-degree pneumatic indexer.
- I have defined two tools in SafeMove, including enclosed geometries, and tied the activation for each to the appropriate indexer output signal.
- The signals that control the solenoid valves for the indexer are cross-connected in the I/O config to simplify programming.
After uploading the SafeMove configuration, when I attempt to move the robot I immediately get the error "90508: Safety Controller Tool Change Incorrect"
Code
Display More90508: Safety Controller Tool Change Incorrect Description Incorrect tool change, in the safety controller for drive module 1. The cause was 1. Consequences The safety controller will stop all robot movements. Operation is not possible until a valid tool has been selected. Causes 1. Invalid tool selection input. 2. Very high speed was detected during the tool change. Actions Check that exactly one tool selection input is active.
So it seems like something is wrong with my I/O or Safe I/O config?
System I/O
doGripperIndex_0
doGripperIndex_90
Safe I/O
Gripper_0 0 BOOL Readers: SC_Feedback_Dev, tGripper_0Deg
Gripper_90 0 BOOL Readers: SC_Feedback_Dev, tGripper_90DegCross Connections
Resultant Actor
Gripper_0 doGripperIndex_0
Gripper_90 doGripperIndex_90
doGripperIndex_90 doGripperIndex_0
Any thoughts here? Do I just need to drop the cross-connect between the 0deg and 90deg signals? Or could I be missing something in the SafeMove setup?