def go_to_bottom(): botcamloc = get_coords() if botcamloc is None: # cancel return noz = machine.getDefaultHead().getDefaultNozzle() if noz is None: return # should error # we don't want to go straight to the cam location--first XY, # then Z safeMoveLocation = Location(botcamloc.getUnits(), botcamloc.getX(), botcamloc.getY(), 0, 0); MovableUtils.moveToLocationAtSafeZ(noz, safeMoveLocation) #machine.defaultHead.defaultNozzle.moveTo(safeMoveLocation) # our default z will be whatever the camera says finalLocation = botcamloc.add(Location(botcamloc.getUnits(), 0,0, botcamloc.getZ(), 0)) ntip = noz.getNozzleTip() if ntip is not None: ntipcalib = ntip.getCalibration() if ntipcalib is not None and ntipcalib.isEnabled(): zoffset = ntipcalib.getCalibrationZOffset() if zoffset is not None: finalLocation = botcamloc.add(Location(zoffset.getUnits(), 0, 0, zoffset.getValue(), 0)) #print("WOULD LIKE TO MOVE TO %s" % str(finalLocation)) MovableUtils.moveToLocationAtSafeZ(noz, finalLocation)
def set_feeder_heights(): nvStore = psypnp.nv.NVStorage(psypnp.config.storagekeys.FeedSearchStorage) selFeeders = psypnp.ui.getSelectedFeeders() defName = nvStore.feedname if len(selFeeders) == 1: defName = selFeeders[0] if defName is None or not len(defName): defName = '8mmStrip' # some default value feedSearch = psypnp.search.prompt_for_feeders_by_name("Name of feeder, or substring thereof to match many", defName) if feedSearch is None or feedSearch.searched is None or not len(feedSearch.searched): return nvStore.feedname = feedSearch.searched if not len(feedSearch.results): psypnp.ui.showError("No feeders match name '%s'" % pname, 'None found') return height = get_height_len() if height is None: return numChanged = 0 for afeeder in feedSearch.results: apart = afeeder.getPart() if apart is not None: pHeight = apart.getHeight() if DoSubtractPartHeightFromLevel: feederHeight = height.subtract(pHeight) else: feederHeight = height refHole = afeeder.getReferenceHoleLocation() if refHole is not None: numChanged += 1 newHole = Location(refHole.getUnits(), refHole.getX(), refHole.getY(), 0, 0) newZ = Location(feederHeight.getUnits(), 0, 0, feederHeight.getValue(), 0) newHole = newHole.add(newZ) psypnp.debug.out.buffer("Setting ref hole for %s to %s" % (afeeder.getName(), str(newHole))) afeeder.setReferenceHoleLocation(newHole) print("Number feeders affected: %i" % numChanged) gui.getFeedersTab().repaint() psypnp.showMessage("Set level Z for %i feeders" % numChanged)
def workspace_centroid(): ''' workspace_centroid find a spot that is in the "middle" of all feed locations. ''' x_tot = 0 y_tot = 0 feed_count = 0 unit_used = None for aFeed in psypnp.globals.machine().getFeeders(): if aFeed and feed_type_supported(aFeed): loc = get_feed_location(aFeed) if loc is None: continue #print(str(loc)) feed_count += 1 x_tot += loc.getX() y_tot += loc.getY() if unit_used is None: unit_used = loc.getUnits() #print(str(unit_used)) if feed_count < 2: return None return Location(unit_used, x_tot / feed_count, y_tot / feed_count, 0, 0)
def feeders_translate(): matchingFeeders = get_feeders_by_name() if matchingFeeders is None or not len(matchingFeeders): return xMoveDistance = psypnp.ui.getUserInputFloat("X displacement", 0.0) yMoveDistance = psypnp.ui.getUserInputFloat("Y displacement", 0.0) if xMoveDistance == 0 and yMoveDistance == 0: return fd1 = matchingFeeders[0] refHole = fd1.getReferenceHoleLocation() lastHole = fd1.getLastHoleLocation() orientationDist = lastHole.subtract(refHole) deltaX = 0.0 deltaY = 0.0 if abs(orientationDist.getX()) > abs(orientationDist.getY()): deltaX = orientationDist.getX() else: deltaY = orientationDist.getY() displacementLocation = Location(refHole.getUnits(), xMoveDistance, yMoveDistance, 0, 0) cleanOrientationDisp = Location(refHole.getUnits(), deltaX, deltaY, 0, 0) numChanged = 0 for afeed in matchingFeeders: refHole = afeed.getReferenceHoleLocation() newLocRefHole = refHole.add(displacementLocation) newLastHole = newLocRefHole.add(cleanOrientationDisp) afeed.setReferenceHoleLocation(newLocRefHole) afeed.setLastHoleLocation(newLastHole) numChanged += 1 psypnp.showMessage("Moved %i feeders" % numChanged)
def get_coords(): cam = machine.defaultHead.defaultCamera curloc = cam.location # get the configured "smallfeed" distance, or default dist = psypnp.nv.get_subvalue( psypnp.config.storagekeys.CrossFeedScripts, psypnp.config.storagekeys.CrossSmallFeedDistance, psypnp.config.distances.SmallFeedDefault) xval = 0 yval = -1 * dist location = curloc.add(Location(LengthUnit.Millimeters, xval, yval, 0, 0)) return location
def get_coords(nozz): curloc = nozz.location xval = psypnp.ui.getUserInputFloat("X", curloc.getX()) if xval is None: # cancel return None yval = psypnp.ui.getUserInputFloat("Y", curloc.getY()) if yval is None: # cancel return None location = Location(LengthUnit.Millimeters, xval, yval, curloc.getZ(), curloc.getRotation()) return location
def go_z(): nozzle = machine.defaultHead.defaultNozzle curloc = nozzle.location zval = psypnp.ui.getUserInputFloat("Go Z", curloc.z) if zval is None: # cancel return if zval > HardLimitMax or zval < HardLimitMin: machine.defaultHead.moveToSafeZ() psypnp.ui.showError("That's crazy talk ( %s < limits < %s) " % (str(HardLimitMin), str(HardLimitMax))) else: loc = Location(LengthUnit.Millimeters, curloc.x, curloc.y, zval, 0) #nozzle.moveTo(loc) MovableUtils.moveToLocationAtSafeZ(nozzle, loc)
def go_angle(): nozzle = machine.defaultHead.defaultNozzle curloc = nozzle.location val = psypnp.ui.getUserInputFloat("Go Rotation", curloc.rotation) if val is None: #cancel return if val < (-1 * HardMaxAngle) or val > HardMaxAngle: psypnp.ui.showError("Only angles <= abs(%s) supported" % str(HardMaxAngle)) return loc = Location(LengthUnit.Millimeters, curloc.x, curloc.y, curloc.z, val) # nozzle.moveTo(loc) MovableUtils.moveToLocationAtSafeZ(nozzle, loc)
def move_nozzle(): nozzle = machine.defaultHead.defaultNozzle location = nozzle.location print_location(location) # Move 10mm right location = location.add(Location(LengthUnit.Millimeters, 10, 0, 0, 0)) print_location(location) nozzle.moveTo(location) # Move 10mm up location = location.add(Location(LengthUnit.Millimeters, 0, 10, 0, 0)) print_location(location) nozzle.moveTo(location) # Move 10mm left location = location.add(Location(LengthUnit.Millimeters, -10, 0, 0, 0)) print_location(location) nozzle.moveTo(location) # Move 10mm down location = location.add(Location(LengthUnit.Millimeters, 0, -10, 0, 0)) print_location(location) nozzle.moveTo(location)
def get_coords(nozz): curloc = nozz.location xval = psypnp.ui.getUserInputFloat("X", 0) if xval is None: # cancel return None yval = psypnp.ui.getUserInputFloat("Y", 0) if yval is None: # cancel return None try: xval = float(xval) except: xval = 0 try: yval = float(yval) except: yval = 0 location = curloc.add(Location(LengthUnit.Millimeters, xval, yval, 0, 0)) return location
from org.openpnp.machine.reference.driver import GcodeDriver from org.openpnp.model import LengthUnit, Location # Move 0,0,0 nozzle.moveToSafeZ() location = nozzle.getLocation() nozzle.moveTo(Location(LengthUnit.Millimeters, 0, 0, location.getZ(), 0)) # Disable calibration nozzleTip.getCalibration().reset() # Turn off backlash driver = machine.getDriver() driver.setBacklashOffsetX(0) driver.setBacklashOffsetY(0)
def check_feeder_heights(): global StorageParentName cur_feeder_index = get_current_idx() #next_feeder_index = get_next_feeder_index(cur_feeder_index) curFeed = get_current_feeder() if curFeed is None: return False if not curFeed.isEnabled(): # we may have a stale current index reset_idx_counter() psypnp.ui.showError("Stale feed index, have reset. Please go again.") return True #curFeed = get_next_feeder_from(next_feeder_index) feederPart = curFeed.getPart() print("Will move to feeder %i\n%s \nwith part \n%s " % (cur_feeder_index, str(curFeed.getName()), str(feederPart.getId()))) # always safeZ machine.defaultHead.moveToSafeZ() # we don't want to go straight to the cam location--first XY, # then Z feedPickLoc = curFeed.getPickLocation() safeMoveLocation = Location(feedPickLoc.getUnits(), feedPickLoc.getX(), feedPickLoc.getY(), 0, 45) MovableUtils.moveToLocationAtSafeZ(machine.defaultHead.defaultNozzle, safeMoveLocation) #print("WOULD MOVE FIRST TO: %s" % str(safeMoveLocation)) locDepthZ = feedPickLoc.getZ() if MinSaneHeightAbs > abs(locDepthZ): print("Something weird with this feed -- height is %s" % str(locDepthZ)) psypnp.ui.showError("Feeder height is strange: %s" % curFeed.getId()) return False # length "down" to bottom of feed pick location, e.g. -35.00 locDepthZLength = Length(locDepthZ, feedPickLoc.getUnits()) # height of part, this is how much above the bottom of the feed pick # location openpnp will travel before picking up partHeight = feederPart.getHeight() actualDepthZTravelled = locDepthZLength if DoSubtractPartHeightFromLevel: print("Removing part height from travel depth") actualDepthZTravelled = locDepthZLength.add(partHeight) # target location "real" depth openpnp will travel (as Location object) locRealDepth = Location(feedPickLoc.getUnits(), 0, 0, actualDepthZTravelled.getValue(), 0) # safe depth to travel to, basically real location depth + MinSaneHeightAbs (mm) locSafeDepth = locRealDepth.add( Location(LengthUnit.Millimeters, 0, 0, MinSaneHeightAbs, 45)) # our first stage move is the (x,y) "safe" location with safe motion down locDownFirstStage = safeMoveLocation.add(locSafeDepth) # go there now machine.defaultHead.defaultNozzle.moveTo(locDownFirstStage) #print("NOW MOVE TO: %s" % str(locDownFirstStage)) # now lets slow down curSpeed = machine.getSpeed() machine.setSpeed(0.25) #locFinalApproach = safeMoveLocation.add(locRealDepth) #locFinalApproach = feedPickLoc.subtract(locRealDepth)Location(feedPickLoc.getUnits(), 0, 0, actualDepthZTravelled.getValue(), 0) locFinalApproach = Location(feedPickLoc.getUnits(), feedPickLoc.getX(), feedPickLoc.getY(), actualDepthZTravelled.getValue(), feedPickLoc.getRotation()) #print("WILL FINALLY MOVE TO: %s" % str(locFinalApproach)) #print("ORIG FEEDPICK LOC: %s" % str(feedPickLoc)) machine.defaultHead.defaultNozzle.moveTo(locFinalApproach) machine.setSpeed(curSpeed) keepShowing = True while keepShowing: sel = psypnp.getOption("Result", "How does %s look?" % curFeed.getName(), [ 'Thrilled!', 'Set Height', 'Up 0.1', 'Down 0.1', 'Up 1', 'Down 1' ]) if sel is None: machine.defaultHead.moveToSafeZ() return False keepShowing = False if sel == 0: # all good increment_idx_counter(cur_feeder_index) machine.defaultHead.moveToSafeZ() return True if sel == 1: # calculate height based on this # take the part height and call the feeder that much lower nozLoc = machine.defaultHead.defaultNozzle.location nozHeight = Length(nozLoc.getZ(), nozLoc.getUnits()) feederHeight = nozHeight if DoSubtractPartHeightFromLevel: print("Adding part height to travel depth") feederHeight = nozHeight.subtract(partHeight) # now get the reference hole location refHole = curFeed.getReferenceHoleLocation() # create a new hole without a Z newHole = Location(refHole.getUnits(), refHole.getX(), refHole.getY(), 0, refHole.getRotation()) # finally, add the feederHeight we determined #newHeight = nozLoc.getZ() newZLoc = Location(feederHeight.getUnits(), 0, 0, feederHeight.getValue(), 0) newHole = newHole.add(newZLoc) #print("WILL Set ref hole for %s to %s" % (feederPart.getName(), str(newHole))) curFeed.setReferenceHoleLocation(newHole) machine.defaultHead.moveToSafeZ() increment_idx_counter(cur_feeder_index) return True if sel == 2: # Up 0.1 feedPickLoc = feedPickLoc.add( Location(LengthUnit.Millimeters, 0, 0, 0.1, 0)) machine.defaultHead.defaultNozzle.moveTo(feedPickLoc) keepShowing = True if sel == 3: # Down 0.1 feedPickLoc = feedPickLoc.subtract( Location(LengthUnit.Millimeters, 0, 0, 0.1, 0)) machine.defaultHead.defaultNozzle.moveTo(feedPickLoc) keepShowing = True if sel == 4: # Up 1 feedPickLoc = feedPickLoc.add( Location(LengthUnit.Millimeters, 0, 0, 1, 0)) machine.defaultHead.defaultNozzle.moveTo(feedPickLoc) keepShowing = True if sel == 5: # Down 1 feedPickLoc = feedPickLoc.subtract( Location(LengthUnit.Millimeters, 0, 0, 1, 0)) machine.defaultHead.defaultNozzle.moveTo(feedPickLoc) keepShowing = True return False
def move_z(distance): nozzle.moveTo( nozzle.location.add(Location(LengthUnit.Millimeters, 0, 0, distance, 0)) )
from __future__ import absolute_import, division from time import sleep from javax.swing.JOptionPane import showMessageDialog from org.openpnp.model import LengthUnit, Location from org.openpnp.machine.reference.driver.GcodeDriver import CommandType from org.openpnp.util.MovableUtils import moveToLocationAtSafeZ vacSensor = machine.defaultHead.getActuatorByName("Vacuum_Sense_0") nozzle = machine.defaultHead.defaultNozzle probe_location = Location(LengthUnit.Millimeters, 0, 0, 0, 0) def move_z(distance): nozzle.moveTo( nozzle.location.add(Location(LengthUnit.Millimeters, 0, 0, distance, 0)) ) def print_location(location): print("Location: {}".format(location.toString())) def probe_contact(travel, vac_threshold=900, settle_time=1, max_moves=11): move_count = 0 sleep(settle_time) # Allow vac to settle vac_level = int(vacSensor.read()) print( "Starting %.2f probe at Z:%.2f, Vac: %d" % (travel, nozzle.location.z, vac_level)
def apply(self): self.resetFeedStats() psypnp.debug.out.flush("Applying feed set changes... ") for feedset in self.sets.entries(): psypnp.debug.out.flush("Handling feed set %s" % str(feedset)) for finfo in feedset.entries(): self.num_feeds_processed += 1 psypnp.debug.out.buffer("Feed %s: " % str(finfo)) opnpFeed = finfo.feed if finfo.available(): psypnp.debug.out.flush("disabling") self.num_feeds_disabled += 1 opnpFeed.setEnabled(False) continue self.num_feeds_enabled += 1 #enable feed psypnp.debug.out.buffer("enabling") opnpFeed.setEnabled(True) # set part opnpPart = finfo.associated_part.part psypnp.debug.out.buffer("setting part to %s" % str(opnpPart)) opnpFeed.setPart(opnpPart) opnpFeed.setMaxFeedCount(finfo.associated_part_maxcapacity) # reset rotation psypnp.debug.out.buffer("zeroing rotation") oldLoc = opnpFeed.getLocation() newLocation = Location(oldLoc.getUnits(), oldLoc.getX(), oldLoc.getY(), oldLoc.getZ(), 0.0) opnpFeed.setLocation(newLocation) psypnp.debug.out.buffer("Reset feed count to 0") opnpFeed.setFeedCount(0) # set tape type for feed, if we can psypnp.debug.out.buffer("TapeType... ", False) if finfo.associated_part.package_description is not None \ and finfo.associated_part.package_description.tapetype: ttypeMap = dict( white=ReferenceStripFeeder.TapeType.WhitePaper, black=ReferenceStripFeeder.TapeType.BlackPlastic, clear=ReferenceStripFeeder.TapeType.ClearPlastic) ttype = finfo.associated_part.package_description.tapetype if ttype in ttypeMap: psypnp.debug.out.buffer("setting tapetype to %s" % ttype) opnpFeed.setTapeType(ttypeMap[ttype]) else: psypnp.debug.out.buffer( "Could not set tapetype to '%s' ?" % str(ttype)) else: psypnp.debug.out.buffer("No tapetype specified? Skipping") psypnp.debug.out.flush("Done with feed.") psypnp.debug.out.flush("Done applying to all feed sets.")
def feeders_align(): matchingFeeders = get_feeders_by_name() if matchingFeeders is None or not len(matchingFeeders): return feedLocations = [] runningStatsX = (0, 0, 0) runningStatsY = (0, 0, 0) for afeeder in matchingFeeders: if afeeder.isEnabled(): refHole = afeeder.getReferenceHoleLocation() if refHole is None or not refHole: print("A feed has no reference hole... hum") else: runningStatsX = updatePosStats(runningStatsX, refHole.getX()) runningStatsY = updatePosStats(runningStatsY, refHole.getY()) if runningStatsX[0] < 2: # enabled count is too low psypnp.ui.showError("Not enough enabled feeds to reliably find pos") return statsX = finalizePosStats(runningStatsX) statsY = finalizePosStats(runningStatsY) print("Final stats: \nX: %s\n\nY: %s" % (statsX, statsY)) targetX = None targetY = None if statsX[1] < statsY[1]: # is a vertical set targetX = statsX[0] # set to average X if not psypnp.ui.getConfirmation( "Effect change?", "Will move vertical set to align with x=%s. Proceed?" % str(targetX)): return else: targetY = statsY[0] # set to average Y if not psypnp.ui.getConfirmation( "Effect change?", "Will move horizontal set to align with y=%s. Proceed?" % str(targetY)): return numChanged = 0 for afeeder in matchingFeeders: refHole = afeeder.getReferenceHoleLocation() if targetX is not None: newX = targetX newY = refHole.getY() elif targetY is not None: newX = refHole.getX() newY = targetY newLoc = Location(refHole.getUnits(), newX, newY, refHole.getZ(), refHole.getRotation()) print("Setting feeder loc to: %s" % str(newLoc)) numChanged += 1 afeeder.setReferenceHoleLocation(newLoc) gui.getFeedersTab().repaint() psypnp.showMessage("Aligned %i feeders" % numChanged)
from __future__ import absolute_import, division from time import sleep from javax.swing.JOptionPane import showMessageDialog from org.openpnp.model import LengthUnit, Location from org.openpnp.machine.reference.driver.GcodeDriver import CommandType from org.openpnp.util.MovableUtils import moveToLocationAtSafeZ vacSensor = machine.defaultHead.getActuatorByName("Vacuum_Sense_0") nozzle = machine.defaultHead.defaultNozzle probe_location = Location(LengthUnit.Millimeters, -2.5, 15, -0.5, 0) def move_z(distance): nozzle.moveTo( nozzle.location.add(Location(LengthUnit.Millimeters, 0, 0, distance, 0))) def print_location(location): print("Location: {}".format(location.toString())) def probe_contact(travel, vac_threshold=900, settle_time=1, max_moves=11): move_count = 0 sleep(settle_time) # Allow vac to settle vac_level = int(vacSensor.read()) print("Starting %.2f probe at Z:%.2f, Vac: %d" % (travel, nozzle.location.z, vac_level)) while vac_level > vac_threshold and move_count < max_moves: move_count += 1
def go_cam(): cam = machine.defaultHead.defaultCamera location = Location(LengthUnit.Millimeters, 0, 0, 0, 0) MovableUtils.moveToLocationAtSafeZ(cam, location)