Jump to content

Help with PCM Program


---
 Share

Recommended Posts

Hello, All, 

 

I wrote a pretty intense program that I'm needing some help on a best approach to tackle a potential issue. 

So unfortunately I can't share too much information, but I'll share what I can. 

The part has 63 curved slots that have (3) potential configurations. The original intent of the program was to be able to run a part, and have the software determine which configuration that particular slot was (it is possible/common for a part to have multiple configurations of slots, so essentially every slot is independent from the others). The way I did that was I have a few check features for each slot, and based on those values it will determine the correct configuration. I have that portion of the program nailed down and working well. 

The challenge now is to be able to only run a specific slot or group of slot(s). 

The way I've handled stuff like this in the past is doing what Zeiss does for the TOA program for the O-Inspect (I have just modified that to work for my needs). I can post that code. 
 

// ==============================
// Slot selection
// ==============================

MAX_SLOTS  = 63
MAX_SELECT = 64

// Initialize arrays
for i = 1 to MAX_SLOTS
	slot[i]  = i
	check[i] = 0
next i

// Special bulk option goes in the extra slot
slot[MAX_SELECT] = "1-63"

// Initialize selection list
for i = 1 to MAX_SELECT
	selectSlot[i] = "-"
next i

// Other state
TypCMM        = ""
AR_slot       = getCFNames()
selectRunMode = getRunID()
cncBreak      = 0
l             = 1    // number of selections gathered (index into selectSlot)

// ==============================
// Run mode handling
// ==============================
selectCase selectRunMode

	// ------------------------------------------
	// DETAIL: interactive picker with ready/cancel
	// ------------------------------------------
	case selectRunMode == "Detail"

		// First pick: allow "1-63" bulk select OR a single slot
		selectSlot[1] = inquireList("Please select the Slot you want to check.", "1-63", slot[1], slot[2], slot[3], slot[4], slot[5], slot[6], slot[7], slot[8], slot[9], slot[10],	slot[11], slot[12], slot[13], slot[14], slot[15], slot[16], slot[17], slot[18], slot[19], slot[20],slot[21], slot[22], slot[23], slot[24], slot[25], slot[26], slot[27], slot[28], slot[29], slot[30], slot[31], slot[32], slot[33], slot[34], slot[35], slot[36], slot[37], slot[38], slot[39], slot[40], slot[41], slot[42], slot[43], slot[44], slot[45], slot[46], slot[47], slot[48], slot[49], slot[50], slot[51], slot[52], slot[53], slot[54], slot[55], slot[56], slot[57], slot[58], slot[59], slot[60], slot[61], slot[62], slot[63], "cancel")

		// Handle cancel
		if selectSlot[1] == "cancel"
			cncBreak = 1
		endif

		// Handle "1-63" bulk selection
		if cncBreak == 0
			if selectSlot[1] == "1-63"
				for m = 1 to MAX_SLOTS
					check[m]      = 1
					selectSlot[m] = slot[m]
				next m
				l = MAX_SELECT
			endif
		endif

		// If a single slot was picked, mark it and remove from future lists
		if cncBreak == 0
			if selectSlot[1] <> "1-63"
				for s = 1 to MAX_SELECT
					if selectSlot[1] == slot[s]
						slot[s]  = ""   // blank so it won't show again
						check[s] = 1
					endif
				next s
			endif
		endif

		// If not bulk-selected and not canceled, keep asking for more
		if cncBreak == 0
			if selectSlot[1] <> "1-63"
				m = 2
				for j = 1 to MAX_SLOTS
					if cncBreak == 1
						j = MAX_SLOTS
					else
						// Offer remaining slots plus controls
						selectSlot[m] = inquireList( "Select additional Slot(s), or choose 'ready' to continue.", slot[1], slot[2], slot[3], slot[4], slot[5], slot[6], slot[7], slot[8], slot[9], slot[10], slot[11], slot[12], slot[13], slot[14], slot[15], slot[16], slot[17], slot[18], slot[19], slot[20], slot[21], slot[22], slot[23], slot[24], slot[25], slot[26], slot[27], slot[28], slot[29], slot[30], slot[31], slot[32], slot[33], slot[34], slot[35], slot[36], slot[37], slot[38], slot[39], slot[40], slot[41], slot[42], slot[43], slot[44], slot[45], slot[46], slot[47], slot[48], slot[49], slot[50], slot[51], slot[52], slot[53], slot[54], slot[55], slot[56], slot[57], slot[58], slot[59], slot[60], slot[61], slot[62], slot[63], "ready", "cancel")

						// Cancel ends selection
						if selectSlot[m] == "cancel"
							cncBreak = 1
							j = MAX_SLOTS
						endif

						// If nothing chosen, prompt again
						if cncBreak == 0
							if selectSlot[m] == ""
								message("Please select a Slot, 'ready', or 'cancel'.")
								// repeat this iteration
								m = m
							else
								// Finish selection
								if selectSlot[m] == "ready"
									j = MAX_SLOTS
								else
									// Record choice, flag check[], and remove from future lists
									for s = 1 to MAX_SELECT
										if selectSlot[m] == slot[s]
											check[s]      = 1
											selectSlot[m] = slot[s]
											slot[s]       = ""   // hide choice from the next prompt
										endif
									next s
									m = m + 1
								endif
							endif
						endif
					endif
				next j

				// Track how many were actually selected (+1 for the initial pick already in selectSlot[1])
				l = m
			endif
		endif

	// ------------------------------------------
	// RUN COMPLETE: select all slots automatically
	// ------------------------------------------
	case selectRunMode == "Run Complete"
		for m = 1 to MAX_SLOTS
			check[m]      = 1
			selectSlot[m] = slot[m]
		next m
		l = MAX_SELECT

	// ------------------------------------------
	// COMPLETE: select all slots (alias behavior)
	// ------------------------------------------
	case selectRunMode == "Complete"
		for m = 1 to MAX_SLOTS
			check[m]      = 1
			selectSlot[m] = slot[m]
		next m
		l = MAX_SELECT

endSelect

// At this point:
//   - check[i] == 1 for chosen slots
//   - selectSlot[1..l-1] contain the chosen labels (numbers)
//   - cncBreak == 1 if user canceled

 

The way this works is that you have a Mini-Plan called "Detail" that all of the characteristics live inside of it, and then you use a condition on the group of characteristics for that respective slot to check if it has been selected to be measured. 

check[1] == 1

If yes, it will measure that group of characteristics, if no it will skip that group. 

This works well for most of my applications that I've used this on except it forces you to run via the Characteristics instead of Features. That will not work for me because it has to run the group of features in order (slot checks first). 

I thought I could get creative and put conditionals on the features (you can place one on the strategy), but while that does skip the measurement of the feature it appears that it will change to that probe used (this is an RDS), so if they only select say slot 1, it will measure slot 1 and then rotate to every stylus tip used for the other ones - creating a lot of unnecessary rotations/movements/calculations. 

 

I'm looking for some guidance on a better solution. 

I thought about making a dynamic Mini-Plan, but I don't know how to do that. 

Any and all help is greatly appreciated. 

Link to comment
Share on other sites

How much dynamic you need?

I don't know how your program is written for group sections, but you could possibly obtain number of groups to have a dynamic number of max slots.

How much you insist on inquireList selection? You could have it easier with just text: "1-12,34,56" this text can be processed to have multiple selection or written as select from-to and exclude with asterisk like: "1-50*34" or even with brackets something.

I know somewhere were shown steps to make dynamic list so you don't need to write all options for select.

 

Unfortunately i don't have an PCM, so i would rely on someone's reaction.

  • Like! 1
Link to comment
Share on other sites

I ended up cheating, and created a group of characteristics for each slot that is the run order. It was the easiest solution to my problem, but I'd like to eventually learn a much better way of handling this issue. 

I went with inquireList instead of inquireText to help with operators not entering the wrong values, but maybe inquireText is a better longer term solution. 

The main issue at the end of it all is that the features have to run in a specific order due to the way it is programmed. I thought the Dynamic Mini-Plan would help make it easier to run from the feature side. 

Link to comment
Share on other sites

Richard, 

 

Certainly a lot going on with this program. So the intent wasn't to have the probe/program automatically start measuring and determine what configuration it is measuring? It relied on operator input and InquireList correct?  I think you did it fairly robust, however I'm sure there are some wizards here who could do it more 'cleaner', but hey as long as it functions, I would be fine with it. 

 One cool thing I just discovered, that I did not know was an option was if cncBreak ==0 , i did not know that was a thing, but thinking about it, makes sense, I don't know that I would use that in my program as it seems it could be susceptible to unwanted errors, etc.

 

At any rate, I might try running your idea by AI/Chat-GPT, although they typically give info for actual Smalltalk code rather than Calypso PCM, but I guess you could teach it PCM.  

 

Good luck.

 

Link to comment
Share on other sites

Chris, 

Yeah - this program is a beast, and there is a lot going on. Yes, unfortunately the operators have no clue as to what the condition of each slot is, so it's up to us measurement guys to figure it out! Lol. 

The original scope of the program actually worked really well. I had (3) check features for each slot, and based on those values, it would make a determination as to which configuration it was and then measure it with the correct nominals. 

The latest issue/request was the ability to run only a specific slot if needed (say there were a few that measured out of specification, and they wanted to clean and re-run the part). Obviously this makes sense because the original program was extremely long, so if you only wanted to measure one slot, or even a few you just didn't want to wait an extended period of time. 

I've done this before, but in all of those cases it didn't matter than I needed to now run from the Characteristics side. That's why I started thinking about dynamic Mini-Plans, but I don't have a lot to go off of for those. Lord Calypso posted an example before, but it was in a proprietary pcm file, so I couldn't really see what was going on under the hood. 

I did run into a fun quirk where if you try to build a list via getCFNames(), it will only build a list so big (maybe a memory thing), but eventually it will just put "...etc..." at the end of the list. Hahaha. 

  • Like! 1
Link to comment
Share on other sites

Please sign in to view this quote.

Richard, 

 Well done, definitely a daunting task.

Regarding re-running only out of tolerance features, have you heard of "Zeiss Dynamic Planning", I think it is a license which will make an option to run only the characteristics out of tolerance or out of control limits, etc, from last run.  This should be easy to do just by writing outOfTol char's to a .txt/.para file, and assign those VARiables to a Mini-Plan VARiable ? I think that's all it does anyhow. Not sure it would work well with a lot of PCM.

Yeah, I've used getCFNames() a few times, and the list looks large. That is funny, that is puts an .."etc".. at the end, I think you should notify Zeiss about that one. Good find. 

 

 

Edited
Link to comment
Share on other sites

Please sign in to view this quote.

Do you mean encrypted PCM files (cfpcm extension)? Well, there are ways to reverse that...

  • Like! 1
Link to comment
Share on other sites

 Share

×
×
  • Create New...