def run(): log.basicConfig(format="[ %(asctime)s ] [ %(levelname)s ] %(message)s", level=log.INFO, stream=sys.stdout) # GrowBot 2 r = Remote("e3dde6f2-5925-42e4-b37d-5214f18ae798", "ws://localhost:8080") print("Test") r.create_log_entry(LogType.UNKNOWN, "Hello, world!") print("Created") asyncio.ensure_future(r.connect()) loop = asyncio.get_event_loop() pending = asyncio.Task.all_tasks() loop.run_until_complete(asyncio.gather(*pending))
class RobotController: model_xml = '/home/student/ssd300.xml' model_bin = '/home/student/ssd300.bin' def __init__(self): self.vision = Vision(RobotController.model_xml, RobotController.model_bin, self, is_headless=True, live_stream=True, confidence_interval=0.5) self.received_frame = None self.qr_reader = QRReader() self.last_qr_approached = None self.current_qr_approached = None self.approach_complete = True self.retrying_approach = False self.standby_mode = True self.standby_invoked = True self.serial_io = SerialIO('/dev/ttyACM0', 115200, self) self.actions = {} self.watered = False if config.RESPOND_TO_API: host = config.API_HOST if config.API_SECURE: host = "wss://" + host else: host = "ws://" + host self.remote = Remote(config.UUID, host) self.remote.add_callback(RPCType.MOVE_IN_DIRECTION, self.remote_move) self.remote.add_callback(RPCType.EVENTS, self.on_events_received) self.remote.add_callback(RPCType.SET_STANDBY, self.set_standby) rm_thread = threading.Thread(target=self.thread_remote, name="remote", daemon=True) rm_thread.start() # rm_thread.join() # Create the navigation system self.navigator = Navigator(self, verbose=True) threading.Thread(target=self.vision.start, name="vision").start() def remote_move(self, direction): self.navigator.remote_move(direction) def run_event(self, event): if self.standby_mode and len(self.actions.keys()) == 0: self.set_standby(False, justMove=True) for action in event.actions: pid = action["plant_id"] if pid not in self.actions: self.actions[pid] = [] self.actions[pid].append(action["name"]) def thread_remote(self): loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) self.sched = Scheduler() self.sched.run_event_cb = self.run_event loop.run_until_complete(self.remote.connect()) def enabled(self): return len(self.actions) > 0 or not self.standby_mode def clean_actions(self): new_actions = {} for key in self.actions: if self.actions[key] != []: new_actions[key] = self.actions[key] self.actions = new_actions def process_visual_data(self, predictions, frame): """ Forwards messages to navigator instance. :param predictions: List of predictions produced by the VPU :return: """ # If the standby is currently undergoing, but standby mode is False, stop standby mode here if self.standby_invoked and not self.standby_mode: self.standby_invoked = False self.random_search_mode = True self.navigator.remote_motor_controller.random() self.standby_invoked = False # If the sensor's last read time is long enough (1 hour), attempt to read the sensor if time.time( ) - self.serial_io.sensor_last_read > 3600 and not self.serial_io.value_reading: threading.Thread(name="serial_read", target=self.serial_io.read_value).start() if self.enabled(): log.info("self.actions: {}, standby_mode: {}".format( self.actions, self.standby_mode)) self.clean_actions() self.received_frame = frame self.navigator.on_new_frame(predictions) else: if self.standby_mode: log.info("\033[0;34m[Pi] Standby mode flag detected") if not self.approach_complete: log.info( "\033[1;37;44m[Pi] Robot approaching, ignoring flag") elif self.retrying_approach: log.info( "\033[1;37;44m[Pi] Robot retrying approach, ignoring flag" ) else: if not self.standby_invoked: self.navigator.remote_motor_controller.stop() log.info("\033[1;37;44m[Pi] Invoking standby mode") # Any other switches to flip? # Reset read QR codes self.current_qr_approached = None self.last_qr_approached = None # Stop the motor self.standby_invoked = True elif len(self.actions) == 0: log.info("\033[0;34m[Pi] Robot has no event left to complete") # Stop immediately? Wait until the jobs to finish to stop? def read_qr_code(self): # Read the QR code tries = 3 qr_codes = self.qr_reader.identify(self.received_frame) while tries > 0: if len(qr_codes) == 0: log.warning("No plant QR found.") tries -= 1 else: for qr in qr_codes: self.current_qr_approached = qr log.info("Plant QR found: {}".format(qr)) break def on_plant_found(self): # Send message to initiate approach command, until instructed to continue if self.current_qr_approached is None: log.warning("No QR found, retrying approach") self.retrying_approach = True self.navigator.remote_motor_controller.retry_approach() elif self.current_qr_approached.startswith("gbpl:"): # Parse the QR plant_id = int(self.current_qr_approached[5:]) if not self.standby_invoked: # If robot is not in standby mode, go forward anyways self.approach_complete = False self.navigator.remote_motor_controller.approached() elif plant_id in self.actions: if len(self.actions[plant_id]) == 0: log.info( "Plant {} has no task left to complete, leaving...". format(str(plant_id))) self.last_qr_approached = self.current_qr_approached self.current_qr_approached = None self.navigator.remote_motor_controller.approach_escape() else: self.approach_complete = False if "PLANT_WATER" in self.actions[ plant_id] or not self.standby_invoked: self.navigator.remote_motor_controller.approached() else: self.navigator.remote_motor_controller.approached( raise_arm=False) else: log.info("Plant {} has no task assigned, leaving...".format( str(plant_id))) self.last_qr_approached = self.current_qr_approached self.current_qr_approached = None self.navigator.remote_motor_controller.approach_escape() else: log.warning("Invalid QR code {}".format( self.current_qr_approached)) self.last_qr_approached = self.current_qr_approached self.current_qr_approached = None self.navigator.remote_motor_controller.approach_escape() def on_approach_complete(self): # Take a picture here plant_id = None if self.current_qr_approached is not None: if self.current_qr_approached.startswith("gbpl:"): plant_id = int(self.current_qr_approached[5:]) if "PLANT_CAPTURE_PHOTO" in self.actions.get( plant_id, []) or not self.standby_invoked: self.remote.plant_capture_photo( int(self.current_qr_approached[5:]), base64.b64encode( cv2.imencode( ".jpg", self.received_frame)[1]).decode("utf-8")) else: log.warning( "[Pi] No QR code found during this approach, photo will not be sent." ) self.last_qr_approached = self.current_qr_approached self.current_qr_approached = None try: if plant_id is not None: if self.watered: self.actions[plant_id].remove("PLANT_WATER") self.watered = False if self.actions[plant_id] == []: self.actions.pop(plant_id, None) self.actions[plant_id].remove("PLANT_CAPTURE_PHOTO") except: pass finally: self.navigator.remote_motor_controller.approach_escape() def on_approach_escape_complete(self): self.navigator.random_search_mode = True # Flip on the random search self.navigator.remote_motor_controller.random_walk() self.clean_actions() self.approach_complete = True def on_retry_complete(self): self.retrying_approach = False self.navigator.approach_frame_counter = 8 def on_plant_seen(self): pass def on_events_received(self, data): events = list(map(Event.from_dict, data)) non_ephemeral = [] for e in events: if e.ephemeral: self.run_event(e) else: non_ephemeral.append(e) self.sched.push_events(non_ephemeral) pass def set_standby(self, mode, justMove=False): if mode: self.standby_mode = True while not hasattr(self, "navigator"): pass self.navigator.remote_motor_controller.stop() return while not hasattr(self, "navigator"): pass # Start random search self.navigator.random_search_mode = True self.navigator.remote_motor_controller.random_walk() if not justMove: # Turn off standby mode self.standby_mode = False def get_state(self): if self.standby_mode: return "Standby Mode" elif self.retrying_approach: return "Retrying approach" elif self.navigator.get_random_search_mode(): return "Random Search Mode" elif self.navigator.get_follow_mode(): return "Follow Mode" elif self.navigator.get_escape_mode(): return "Escape Mode"
def sign(self, callback): from jingtum_python_baselib.src.wallet import Wallet as base #导入Serializer 目前未实现 from remote import Remote #2018.6.2 remote类没有翻译完整 remote = Remote({'server': self._remote._url}) def connect_callback(err, result): if (err is not None): callback(err) req = remote.requestAccountInfo({ 'account': self.tx_json.Account, 'type': 'trust' }) req.submit(submit_callback) def submit_callback(err, data): if (err is not None): return callback(err) self.tx_json['Sequence'] = data.account_data.Sequence self.tx_json['Fee'] = self.tx_json['Fee'] / 1000000 #payment if (self.tx_json.Amount and json.dumps(self.tx_json.Amount).index('{') < 0): #基础货币 self.tx_json.Amount = Number(self.tx_json.Amount) / 1000000 if (self.tx_json['Memos'] is not None): memo_list = self.tx_json['Memos'] memo_list[0]["Memo"]["MemoData"] = __hexToString( memo_list[0]["Memo"]["MemoData"]).decode('UTF-8') if (self.tx_json['SendMax'] is not None and isinstance(self.tx_json['SendMax'], str)): self.tx_json['SendMax'] = Number( self.tx_json['SendMax']) / 1000000 #order if (self.tx_json['TakerPays'] and json.dumps(self.tx_json['TakerPays']).index('{') < 0): #基础货币 self.tx_json['TakerPays'] = Number( self.tx_json['TakerPays']) / 1000000 if (self.tx_json['TakerGets'] and json.dumps(self.tx_json['TakerGets']).index('{') < 0): #基础货币 self.tx_json['TakerGets'] = Number( self.tx_json['TakerGets']) / 1000000 #2018.6.3 wallet类没有翻译完整 """ wt = base(self._secret) self.tx_json['SigningPubKey'] = wt.getPublicKey() prefix = 0x53545800 hash = jser.from_json(self.tx_json).hash(prefix) self.tx_json['TxnSignature'] = wt.signTx(hash) self.tx_json['blob'] = jser.from_json(self.tx_json).to_hex() """ self._local_sign = True callback(None, self.tx_json['blob']) remote.connect(connect_callback)