def zap_weeds(): device.execute(weeder_tool_retrieve_sequence_id) coord = Coordinate(device.get_current_position('x'), device.get_current_position('y')) for weed_point in weed_points: coord.set_coordinate(z=Z_TRANSLATE) # move up to translate height coord.set_coordinate(weed_point['x'] + LASER_OFFSET_X, weed_point['y'] + LASER_OFFSET_Y) # move to point coord.set_axis_position('z', ZAP_HEIGHT) # move down to zapping height coord.set_offset(-(AREA_SIZE / 2), -(AREA_SIZE / 2)) # offset x and y half of area coord.set_speed(ZAP_SPEED) device.write_pin(PIN_ZAPPER, 1, 0) for i in range(AREA_SIZE): if coord.get_offset_axis_position('x') > 0: #coord.set_offset_axis_position('x', -(AREA_SIZE / 2)) for j in range(AREA_SIZE): coord.set_offset_axis_position('x', (AREA_SIZE / 2) - j - 1) device.wait(ZAP_TIMEOUT) else: #coord.set_offset_axis_position('x', AREA_SIZE / 2) for j in range(AREA_SIZE): coord.set_offset_axis_position('x', -(AREA_SIZE / 2) + j + 1) device.wait(ZAP_TIMEOUT) coord.set_offset_axis_position( 'y', coord.get_offset_axis_position('y') + 1) device.write_pin(PIN_ZAPPER, 0, 0) coord.set_speed(100) coord.set_offset(0, 0) coord.set_coordinate(z=Z_TRANSLATE) device.execute(weeder_tool_return_sequence_id)
def move_and_capture(self): """Move the bot along x and y axes, take photos, and detect circles.""" for i, move in enumerate(RELATIVE_MOVEMENTS): if i > 0: log('Moving to next camera calibration photo location.', message_type='info', title='camera-calibration') if USE_FARMWARE_TOOLS: device.move_relative(move['x'], move['y'], move['z'], 100) else: CeleryPy.move_relative((move['x'], move['y'], move['z']), speed=100) log('Taking camera calibration photo. ({}/3)'.format(i + 1), message_type='info', title='camera-calibration') img_filename = self.capture() if USE_FARMWARE_TOOLS: coordinates = device.get_current_position() for axis, coordinate in coordinates.items(): coordinates[axis] = float(coordinate) else: coordinates = {'z': 0} img = cv2.imread(img_filename, 1) os.remove(img_filename) ret, centers = self.find_pattern(img) if not self.success_flag: self.save_image(img, str(i + 1)) return self.success_flag self.dot_images[i]['circles'] = centers self.dot_images[i]['found'] = ret self.dot_images[i]['image'] = img self.dot_images[i]['coordinates'] = coordinates return self.success_flag
def move_and_capture(self): """Move the bot along x and y axes, take photos, and detect circles.""" for i, movement in enumerate(RELATIVE_MOVEMENTS): if i > 0: if self.relative_starting_position is None: self.relative_starting_position = {'x': 0, 'y': 0, 'z': 0} log('Moving to next camera calibration photo location.', message_type='info', title='camera-calibration') self._move(movement) for axis in movement: self.relative_starting_position[axis] -= movement[axis] log('Taking camera calibration photo. ({}/3)'.format(i + 1), message_type='info', title='camera-calibration') img_filename = self.capture() if USE_FARMWARE_TOOLS: coordinates = device.get_current_position() for axis, coordinate in coordinates.items(): coordinates[axis] = float(coordinate) else: coordinates = {'z': 0} img = cv2.imread(img_filename, 1) os.remove(img_filename) ret, centers = self.find_pattern(img, True) if not self.success_flag: self.save_image(img, str(i + 1)) return self.success_flag self.dot_images[i]['circles'] = centers self.dot_images[i]['found'] = ret self.dot_images[i]['image'] = img self.dot_images[i]['coordinates'] = coordinates self.return_to_start() return self.success_flag
def weed_scan(): """ pause before taking image """ def plant_detection(): device.wait(1000) device.execute_script(label='plant-detection') """ scans length of X axis """ def scan_line(): while device.get_current_position('x') < X_MAX: if coord.get_axis_position('x') + X_MOVE > X_MAX: coord.set_axis_position('x', X_MAX) else: coord.set_axis_position('x', coord.get_axis_position('x') + X_MOVE) plant_detection() """ start scan """ coord = Coordinate(X_START, Y_START) coord.move_abs() device.execute_script(label='plant-detection') scan_line() while device.get_current_position('y') < Y_MAX: if coord.get_axis_position('y') + Y_MOVE > Y_MAX: coord.set_coordinate(X_START, Y_MAX) else: coord.set_coordinate(X_START, coord.get_axis_position('y') + Y_MOVE) coord.move_abs() plant_detection() scan_line() device.sync() device.log('Scan Complete.', 'info', ['toast'])
def scan_line(): while device.get_current_position('x') < X_MAX: if coord.get_axis_position('x') + X_MOVE > X_MAX: coord.set_axis_position('x', X_MAX) else: coord.set_axis_position('x', coord.get_axis_position('x') + X_MOVE) plant_detection()
def take_readings(): plants_chosen = [] device.execute(moisture_tool_retrieve_sequence_id) #coord = Coordinate(device.get_current_position('x'), device.get_current_position('y'), Z_TRANSLATE) #device.log('Creating Coordinate') bot = Coordinate(device.get_current_position('x'), device.get_current_position('y')) bot.set_offset(OFFSET_X, OFFSET_Y, move_abs=False) # sets the offset, auto-move disabled #device.log('BOT: {}'.format(bot)) for i in range(NUM_SITES): rand_plant_num = randint(0, len(target_plants) - 1) while rand_plant_num in plants_chosen: rand_plant_num = randint(0, len(target_plants) - 1) plants_chosen.append(rand_plant_num) rand_plant = target_plants[rand_plant_num] device.log('Random Plant: {}'.format(json.dumps(rand_plant))) bot.set_axis_position( 'z', Z_TRANSLATE ) # sets the z axis to translate height, auto-move enabled bot.set_coordinate( rand_plant['x'], rand_plant['y']) # set the plant coordinate, auto-move enabled bot.set_axis_position( 'z', SENSOR_Z_DEPTH) # plunge sensor into soil, auto-move enabled # take reading(s) site_readings = [] for j in range(NUM_SAMPLES): device.read_pin(PIN_SENSOR, 'Sensor', 1) site_readings.append(device.get_pin_value(PIN_SENSOR)) device.wait(100) average = 0 for reading in site_readings: average += reading average /= NUM_SAMPLES moisture_readings.append(average) device.log('Site Reading #{}: {}'.format(i, average), 'success') bot.set_axis_position('z', Z_TRANSLATE) device.log('Readings: {}'.format(json.dumps(moisture_readings)), 'success') device.execute(moisture_tool_return_sequence_id)
def sort_points(points, use_simple_sort=False): """ Sort the points """ if not use_simple_sort and len(points) > 0: # Get current location curr_pos = device.get_current_position() # this is for local debugging purposes, when running `python main.py` if curr_pos is None: curr_pos = {"x": 0, "y": 0} return PointSort.sort_points_by_dist(points, curr_pos) else: return PointSort.sort_points_basic(points)
def _get_raw_coordinate_values(self, redis=None): temp = [] if USE_FARMWARE_TOOLS and redis is None: coord = device.get_current_position() or {} return [coord.get('x'), coord.get('y'), coord.get('z')] legacy = int(os.getenv('FARMBOT_OS_VERSION', '0.0.0')[0]) < 6 if legacy: for axis in ['x', 'y', 'z']: temp.append( ENV.redis_load('location_data.position.' + axis, other_redis=redis)) else: state = self._get_bot_state() for axis in ['x', 'y', 'z']: try: value = state['location_data']['position'][str(axis)] except KeyError: value = None temp.append(value) return temp
'''Fotos_highres_with_Names. Take a photo using a USB or Raspberry Pi camera. ''' import os import time import json import requests import numpy as np import cv2 import sys from farmware_tools import device, app try: points = app.get_plants() #Get all points from webapp, would be smarter to get plants, will try that later position_x = int(round(device.get_current_position('x'))) #Actual X-Position position_y = int(round(device.get_current_position('y'))) #Actual Y-Position all_plants = [] except KeyError: log("Loading points/positions failed","error") def farmware_api_url(): major_version = int(os.getenv('FARMBOT_OS_VERSION', '0.0.0')[0]) base_url = os.environ['FARMWARE_URL'] return base_url + 'api/v1/' if major_version > 5 else base_url def log(message, message_type): 'Send a message to the log.' try:
''' Perhaps, the arm should move to a safe 'beginning' position, defined by the limit switches. It would also need to TRY to understand if it is in a precarious place and if movement in any direction will harm plants, the machine, or whatever. Perhaps, it could attempt to 'see' if it is in a precarious place by using the camera. Maybe little movements in each direction to start. Snap pic, attempt to find its location. It will also be GREAT practice to have the machine move to the safe location at the end of each program like you did in this one. We could use the limit switches to accomplish our safe position by going at slow speed until it's activated on all sides and then we have our, starting position = safe position. ''' start_arm_x = device.get_current_position('x') start_arm_y = device.get_current_position('y') start_arm_z = device.get_current_position('z') safeZ = -200 ''' values for opencv pos_x = 1013 pos_y = 24 pos_z = -400 ''' legacy = get_config_value('Seeding Path', 'Legacy Seeder')#User inputs 0 for false and 1 for true. # Load inputs from Farmware page widget specified in manifest file pos_x = get_config_value('Seeding Path', 'start_x')#Starting X position of Pathway pos_y = get_config_value('Seeding Path', 'start_y')#Starting Y position of Pathway pos_z = get_config_value('Seeding Path', 'start_z')
# Initialise row (X) and column (Y) indexes for all grids rowGrid1Index = 0 colGrid1Index = 0 rowGrid2Index = 0 colGrid2Index = 0 # Initialise the current Position Found flags to not found currentPositionGrid1Found = False currentPositionGrid2Found = False # Set constant Z positions zPosGrid1 = startZGrid1 zPosGrid2 = startZGrid2 # Get the current position for x and y currentPosition = device.get_current_position() currentPositionXstr = str(currentPosition['x']) currentPositionX = int(currentPositionXstr.split('.')[0]) currentPositionYstr = str(currentPosition['y']) currentPositionY = int(currentPositionYstr.split('.')[0]) # Start the first grid movement for rowGrid1Index in range(rowsGrid1): # Set first grids y position back to the first column yPosGrid1 = startYGrid1 for colGrid1Index in range(colsGrid1): # Set the x and y positions on the first grid if alternateInBetween assume the first # column is not an alternateInBetween then odd numbered colums are # if startLastRowOfGrid1 then the x position starts on the last row and moves backwards if alternateInBetweenGrid1 == 1 :
Logger.FARMWARE_NAME = FARMWARE_NAME try: # create new instance of the InputStore. this will load the user input or defaults input_store = InputStore(FARMWARE_NAME, defaults=INPUT_DEFAULTS) # set logger level Logger.set_level(input_store.input["debug"]) log( "Started with python version {}".format(sys.version_info), message_type="info", title="init", ) currpos = device.get_current_position() # currpos = {'x': 0, 'y': 0} if currpos is None else currpos currpos = ({ "x": 650, "y": 880 } if currpos is None else currpos) # arugula default for debugging # currpos = {'x': 680, 'y': 380} if currpos is None else currpos # radish # init instances water_dose = WaterDose(FARMWARE_NAME, input_store.input) control = Control(FARMWARE_NAME) # load the plants plant_search_radius = input_store.input["plant_search_radius"] plants = Plants( FARMWARE_NAME,
device.log('PLANT TYPES: {}'.format(json.dumps(PLANT_TYPES))) all_plants = app.get_plants() target_plants = [] for plant in all_plants: plant_name = ''.join(plant['name'].split()).lower() if plant_name in PLANT_TYPES: target_plants.append(plant) if len(target_plants): # output target plants device.log('Num Plants: {}'.format(len(target_plants))) device.log('Target Plants: {}'.format(json.dumps(target_plants))) else: device.log('No plants found with name(s): "{}"'.format( json.dumps(PLANT_TYPES))) sys.exit() device.write_pin(PIN_LIGHTS, 1, 0) #device.execute(tool_water_retrieve_sequence_id) bot = Coordinate(device.get_current_position('x'), device.get_current_position('y'), TRANSLATE_HMEIGHT) bot.move_abs() for plant in target_plants: bot.set_coordinate(x=plant['x'], y=plant['y']) #device.execute(tool_water_return_sequence_id) device.home('all') device.write_pin(PIN_LIGHTS, 0, 0)
#!/usr/bin/env python ''' ' Single Axis ''' import os from farmware_tools import device from farmware_tools import app from farmware_tools import get_config_value # create Celery coordinate node coord = device.assemble_coordinate(0, 0, 0) # apply currrent positions to coordinate node for axis in coord['args']: coord['args'][axis] = device.get_current_position(axis) # get the desired axis to modify and set the coordinate node to the desired value single_axis = get_config_value('Single Axis', 'axis', str).lower() coord['args'][single_axis] = int(get_config_value('Single Axis', 'pos')) #log = 'Axis: {}, Coordinate: {}'.format(single_axis, coord) log = "Moving '%s' axis to %d" % (single_axis.upper(), coord['args'][single_axis]) device.log(log, 'info', ['toast']) # perform the move device.move_absolute(coord, 100, device.assemble_coordinate(0, 0, 0))
path = images_dir + os.sep + filename return path def rpi_camera_photo(): 'Take a photo using the Raspberry Pi Camera.' from subprocess import call try: filename_path = upload_path(image_filename()) retcode = call( ["raspistill", "-w", "640", "-h", "320", "-o", filename_path]) if retcode == 0: log("Image saved: {}".format(filename_path), "success") else: log("Problem getting image.", "error") except OSError: log("Raspberry Pi Camera not detected.", "error") if __name__ == '__main__': position_x = int(round( device.get_current_position('x'))) # Actual X-Position position_y = int(round( device.get_current_position('y'))) # Actual Y-Position hdd_path = detect_usb_name() mount_usb_drive() rpi_camera_photo() unmount_usb_drive()
'tool_moisture_return') water_tool_retrieve_sequence_id = Qualify.sequence(PKG, 'tool_water_retrieve') water_tool_return_sequence_id = Qualify.sequence(PKG, 'tool_water_return') water_sequence_id = Qualify.sequence(PKG, 'water_sequence') moisture_readings = [] if len(input_errors): for err in input_errors: device.log(err, 'warn') device.log('Fatal config errors occured, farmware exiting.', 'warn') sys.exit() else: device.log('No config errors were detected.', 'success') if device.get_current_position('x') > 10 or device.get_current_position( 'y') > 10 or device.get_current_position('z') < -10: device.home('all') device.write_pin(PIN_LIGHTS, 1, 0) target_plants = [] all_plants = app.get_plants() for plant in all_plants: plant_name = ''.join(plant['name'].split()).lower() Debug.log('plant[\'name\']: {}'.format(plant_name)) if plant_name in PLANT_TYPES: target_plants.append(plant) device.log('Target Plants: {}'.format(json.dumps(target_plants))) sys.exit()
#!/usr/bin/env python """Move To Safe Farmware""" from farmware_tools import device from farmware_tools import get_config_value # Load inputs from Farmware page widget specified in manifest file z_height = get_config_value('Move To Safe', 'safe_z') pos_x = device.get_current_position('x') pos_y = device.get_current_position('y') pos_z = z_height device.log('Moving to ' + str(pos_x) + ', ' + str(pos_y) + ', ' + str(pos_z), 'success', ['toast']) device.move_absolute( { 'kind': 'coordinate', 'args': { 'x': pos_x, 'y': pos_y, 'z': pos_z } }, 100, { 'kind': 'coordinate', 'args': { 'x': 0, 'y': 0, 'z': 0 }