예제 #1
0
def main():
    cam_pipes, depth_scale = c_man.get_pipes()
    #print("{} pipes created!".format(len(cam_pipes)))

    dec_filter = rs.decimation_filter()
    dep_scan = im_scan.scan_portait()

    traj_recv = Trajectory_Reciever()
    stay_go_sender = Publisher(3500)

    while True:
        frameset = c_man.get_frames(cam_pipes, dec_filter)
        scan_mat = dep_scan.get_portrait_from_frames(frameset, depth_scale)

        #dep_scan.conv_reduce()
        _, trans_position = dep_scan.get_pose()
        xz_pos = np.delete(trans_position, 1, axis=0)

        x_vel, y_vel = traj_recv.get_trajectory()
        control_vec = dep_scan.vector_from_vel(x_vel, y_vel)

        print("!dir_vec: ", control_vec)
        soft_danger, rgb_mat = real_oord_test(dep_scan,
                                              dir_vec=control_vec,
                                              position=xz_pos)

        stay_go_sender.send({"soft_danger": soft_danger})
        print("-------------------------pass_fail: ", soft_danger)
        cv2.imshow("circumstances", rgb_mat)

        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

    cv2.destroyAllWindows()
예제 #2
0
def main():
    cv_publisher = Publisher(105)
    MODELS_DIR = '/home/cerbaris/pupper_code/PupperPy/pupperpy/Vision/models/'
    MODEL_PATH = MODELS_DIR + 'ssd_mobilenet_v2_pupper_quant_edgetpu.tflite'
    LABEL_PATH = MODELS_DIR + 'pupper_labels.txt'
    LOG_FILE = '/home/cerbaris/pupper_code/PupperPy/pupperpy/Vision/vision_log.txt'
    labels = dataset_utils.read_label_file(LABEL_PATH)
    engine = DetectionEngine(MODEL_PATH)

    with picamera.PiCamera() as camera:
        camera.resolution = (640, 480)
        camera.framerate = 30
        _, height, width, _ = engine.get_input_tensor_shape()
        try:
            stream = io.BytesIO()
            #count = 0
            for _ in camera.capture_continuous(stream, format='rgb', use_video_port=True, resize=(width, height)):
                stream.truncate()
                stream.seek(0)
                input_tensor = np.frombuffer(stream.getvalue(), dtype=np.uint8)
                #image = Image.frombuffer('RGB',(width,height), stream.getvalue())
                image = Image.frombuffer('RGB',(320,304), stream.getvalue()) # to account for automatic upscaling by picamera when format='rgb'
                #draw = ImageDraw.Draw(image)
                start_ms = time.time()
                results = engine.detect_with_image(image,threshold=0.2,keep_aspect_ratio=True,relative_coord=False,top_k=10)
                elapsed_ms = time.time() - start_ms
                
                detectedObjs = []
                for obj in results:
                    if (obj.label_id in range(3)):
                        box = obj.bounding_box.flatten().tolist()
                        #draw.rectangle(box, outline='red')
                        #draw.text((box[0],box[1]), labels[obj.label_id] + " " + str(obj.score))
                        w = box[0] - box[2]
                        h = box[1] - box[3]
                        objInfo = {'bbox_x':float(box[0]),
                                   'bbox_y':float(box[1]),
                                   'bbox_h':float(h),
                                   'bbox_w':float(w),
                                   'bbox_label':labels[obj.label_id],
                                   'bbox_confidence': float(obj.score)
                                   }
                        detectedObjs.append(objInfo)
                try:
                    cv_publisher.send(detectedObjs)
                except BaseException as e:
                    print('Failed to send bounding boxes. CV UDP subscriber likely not initialized')
                    pass
                #print(detectedObjs)

                #with open('/home/cerbaris/pupper_code/PupperPy/pupperpy/Vision/test_images_120120/' + str(count) + '.png','wb') as f:
                #    image.save(f)
                #count+=1
        except BaseException as e:
            with open(LOG_FILE,'w') as f:
                f.write("Failed to run detection loop:\n {0}\n".format(traceback.format_exc()))
def main(argv):

    shutter = int(argv[0])
    iso = 400

    cam_params = {"shutter": shutter, "iso": iso}
    reference = Publisher(9010)

    camera = picamera.PiCamera(sensor_mode=2,
                               resolution=capture_res,
                               framerate=10)
    camera.shutter_speed = shutter
    camera.iso = iso

    while True:
        image = np.empty((capture_res[1] * capture_res[0] * 3), dtype=np.uint8)
        camera.capture(image, 'bgr')
        image = image.reshape((capture_res[1], capture_res[0], 3))
        img_h, img_w = image.shape[0:2]

        truth = image[int(img_h * 0):int(img_h * 0.3),
                      int(img_w * 0):int(img_w * 0.3), :]
        truth_hsv = cv2.cvtColor(truth, cv2.COLOR_BGR2HSV)

        fname = "truth.jpg"
        cv2.imwrite(fname, truth)

        brightpoint = np.percentile(truth_hsv[:, :, 2], 95)
        toobright = brightpoint > 180
        toodark = brightpoint < 80

        if (toodark or toobright):
            if toobright:
                iso -= iso_step

            if toodark:
                iso += iso_step

            iso = max(ISO_MIN, min(iso, ISO_MAX))
            camera.iso = iso

            print("ISO changed: %d" % (iso))
            continue

        # exposure is ok, let's send over reference colors
        cam_params["range_hue"] = np.percentile(truth_hsv[:, :, 0],
                                                (5, 95)).tolist()
        cam_params["range_sat"] = np.percentile(truth_hsv[:, :, 1],
                                                (5, 95)).tolist()
        cam_params["range_val"] = np.percentile(truth_hsv[:, :, 2],
                                                (5, 95)).tolist()
        cam_params["iso"] = iso
        reference.send(cam_params)

        print(cam_params)
class Logger:
    def __init__(self, port):
        self.pub = Publisher(port)
        self.points = []

    def next(self):
        self.pub.send(self.points)
        self.points = []

    def add(self, pose, color):
        self.points.append([(pose.x, pose.y), pose.a, color])
def main():
    cv_publisher = Publisher(105)
    MODELS_DIR = '/home/cerbaris/pupper_code/PupperPy/pupperpy/Vision/models/'
    MODEL_PATH = MODELS_DIR + 'ssd_mobilenet_v2_coco_quant_postprocess_edgetpu.tflite'
    LABEL_PATH = MODELS_DIR + 'coco_labels.txt'
    LOG_FILE = '/home/cerbaris/pupper_code/PupperPy/pupperpy/Vision/vision_log.txt'
    labels = dataset_utils.read_label_file(LABEL_PATH)
    engine = DetectionEngine(MODEL_PATH)

    with picamera.PiCamera() as camera:
        camera.resolution = (640, 480)
        camera.framerate = 30
        _, height, width, _ = engine.get_input_tensor_shape()
        
        stream = io.BytesIO()
        count = 0
        for _ in camera.capture_continuous(stream, format='rgb', use_video_port=True, resize=(width, height)):
            stream.truncate()
            stream.seek(0)
            input_tensor = np.frombuffer(stream.getvalue(), dtype=np.uint8)
            #image = Image.frombuffer('RGB',(width,height), stream.getvalue())
            image = Image.frombuffer('RGB',(320,304), stream.getvalue()) # to account for automatic upscaling by picamera when format='rgb'
            draw = ImageDraw.Draw(image)
            start_ms = time.time()
            results = engine.detect_with_image(image,threshold=0.1,keep_aspect_ratio=True,relative_coord=False,top_k=51)
            elapsed_ms = time.time() - start_ms
                
            detectedObjs = []
            for obj in results:
                if (obj.label_id == 0 or obj.label_id == 36):
                    if (obj.label_id == 36):
                        print('Tennis ball detected')
                    box = obj.bounding_box.flatten().tolist()
                    draw.rectangle(box, outline='red')
                    draw.text((box[0],box[1]), labels[obj.label_id] + " " + str(obj.score))
                    w = box[0] - box[2]
                    h = box[1] - box[3]
                    objInfo = {'bbox_x':float(box[0]),
                               'bbox_y':float(box[1]),
                               'bbox_h':float(h),
                               'bbox_w':float(w),
                               'bbox_label':labels[obj.label_id],
                               'bbox_confidence': float(obj.score)
                               }
                    detectedObjs.append(objInfo)
            cv_publisher.send(detectedObjs)
            #print(detectedObjs)

            with open('/home/cerbaris/pupper_code/PupperPy/pupperpy/Vision/test_images/' + str(count) + '.png','wb') as f:
                image.save(f)
            count+=1
예제 #6
0
class Sim:
    def __init__(self):
        self.master = tk.Tk()
        self.canvas = tk.Canvas(self.master, width=800, height=200, bg="white")
        self.canvas.pack()

        self.robot = Robot(200)

        self.master.bind('<Left>', lambda e: self.robot.change_speed(-1))
        self.master.bind('<Right>', lambda e: self.robot.change_speed(+1))
        self.master.bind('<space>', lambda e: self.robot.stop())

        self.pub = Publisher(8810, "127.0.0.1")

        self.canvas.create_rectangle(0, 100, 800, 200, fill="blue")
        self.canvas.create_rectangle(0, 0, 10, 200, fill="blue")

        self.master.after(0, self.update)
        tk.mainloop()

    def update(self):
        self.robot.update()

        self.publish(self.robot)
        self.plot(self.robot)

        self.master.after(RATE, self.update)

    def publish(self, robot):
        truth = robot.pos
        pos = robot.pos + random.gauss(0, 40)
        vel = robot.vel + random.gauss(0, 5)

        msg = {"truth": truth, "dist": pos, "vel": vel}
        try:
            self.pub.send(msg)
        except:
            pass

    def plot(self, robot):
        if (robot.id != None):
            self.canvas.delete(robot.id)

        robot.id = self.canvas.create_rectangle(robot.pos,
                                                50,
                                                robot.pos + 100,
                                                100,
                                                fill="red")
예제 #7
0
def main(argv):
    idx_camera = int(argv[0])
    offset_degrees = float(argv[1])

    reference = Subscriber(9010)
    detection_results = Publisher(902 + idx_camera)

    camera = picamera.PiCamera(sensor_mode=2,
                               resolution=capture_res,
                               framerate=10)
    cam_params = {}
    while True:
        try:
            cam_params = reference.get()
            print(cam_params)
        except UDPComms.timeout:
            if "range_hue" not in cam_params:
                continue

        camera.shutter_speed = cam_params["shutter"]
        camera.iso = cam_params["iso"]

        image = np.empty((capture_res[1] * capture_res[0] * 3), dtype=np.uint8)
        camera.capture(image, 'bgr')
        image = image.reshape((capture_res[1], capture_res[0], 3))

        hsv_ranges = (cam_params["range_hue"], cam_params["range_sat"],
                      cam_params["range_val"])

        heading, distance = find_ball_direct(image, hsv_ranges, offset_degrees)

        if (distance > 0):
            result = {"heading": heading, "distance": distance}
            detection_results.send(result)

            print("Found ball!")
            print(result)
예제 #8
0
middle_odrive.axis0.controller.config.vel_gain = .2
middle_odrive.axis1.controller.config.vel_gain = .2
back_odrive.axis0.controller.config.vel_gain = .2
back_odrive.axis1.controller.config.vel_gain = .2
#print front_odrive.axis0.controller.config
while True:
    try:
        msg = cmd.get()
        print(msg)

        try:
            telemetry.send([
                middle_odrive.vbus_voltage,
                front_odrive.axis0.motor.current_control.Iq_measured,
                front_odrive.axis1.motor.current_control.Iq_measured,
                middle_odrive.axis0.motor.current_control.Iq_measured,
                middle_odrive.axis1.motor.current_control.Iq_measured,
                back_odrive.axis0.motor.current_control.Iq_measured,
                back_odrive.axis1.motor.current_control.Iq_measured
            ])
        except:
            pass

        clear_errors(front_odrive)
        clear_errors(middle_odrive)
        clear_errors(back_odrive)

        if (msg['t'] == 0 and msg['f'] == 0):
            send_state(front_odrive, AXIS_STATE_IDLE)
            send_state(middle_odrive, AXIS_STATE_IDLE)
            send_state(back_odrive, AXIS_STATE_IDLE)
예제 #9
0
    on_right = values['button_r1']
    on_left  = values['button_l1']

    square   = values['button_square']
    x        = values['button_cross']
    circle   = values['button_circle'] 
    triangle = values['button_triangle']

    d_pad_x = values['dpad_right'] - values['dpad_left']
    d_pad_y = values['dpad_up']    - values['dpad_down']

    msg = { "ly" : forward_left,
            "lx" : twist_left,
            "rx" : twist_right,
            "ry" : forward_right,
            "L2" : L2,
            "R2" : R2,
            "R1" : on_right,
            "L1" : on_left,
            "dpady" : d_pad_y,
            "dpadx" : d_pad_x,
            "x": x,
            "square": square,
            "circle": circle,
            "triangle": triangle,
            "message_rate" : MESSAGE_RATE
         }
    drive_pub.send(msg)
    time.sleep(1/MESSAGE_RATE)
예제 #10
0
class Control(object):
    STATES = ['off', 'rest', 'meander', 'goto', 'avoid']
    SCREEN_MID_X = 150

    def __init__(self, target='tennis_ball'):
        self.timer = RepeatTimer(1 / MESSAGE_RATE, self._step)
        self.control_state = ControllerState()
        self.pos = PositionTracker(self.control_state)
        self.obj_sensors = ObjectSensors()
        self.active = False
        self.walking = False
        self.user_stop = False
        self.cmd_pub = Publisher(CMD_PUB_PORT)
        self.cmd_sub = Subscriber(CMD_SUB_PORT)
        self.cv_sub = Subscriber(CV_SUB_PORT)
        self.joystick = Joystick()
        self.joystick.led_color(**PUPPER_COLOR)
        self.state = 'off'
        self.target = target
        self.current_target = None
        self.pusher_client = PusherClient()
        self._last_sensor_data = (None, None, None)

    def move_forward(self, vel=ControllerState.LEFT_ANALOG_Y_MAX):
        self.control_state.left_analog_y = vel

    def move_backward(self, vel=-ControllerState.LEFT_ANALOG_Y_MAX):
        self.control_state.left_analog_y = vel

    def move_stop(self):
        self.control_state.left_analog_y = 0

    def turn_right(self, rate=ControllerState.RIGHT_ANALOG_X_MAX):
        self.control_state.right_analog_x = rate

    def turn_left(self, rate=-ControllerState.RIGHT_ANALOG_X_MAX):
        self.control_state.right_analog_x = rate

    def turn_stop(self):
        self.control_state.right_analog_x = 0

    def start_walk(self):
        if self.walking or not self.active:
            return

        self.reset()
        self.control_state.r1 = True
        self.toggle_cmd()
        self.walking = True
        self.control_state.walking = True
        self.reset()

    def activate(self):
        if self.active:
            return

        self.reset()
        self.control_state.l1 = True
        self.toggle_cmd()
        self.reset()

        self.active = True
        self.state = 'rest'
        self.walking = False
        self.control_state.walking = False
        if not self.pos.running:
            self.pos.run()

    def stop_walk(self):
        if not self.walking:
            return

        self.reset()
        self.control_state.r1 = True
        self.toggle_cmd()
        self.walking = False
        self.control_state.walking = False
        self.reset()
        self.state = 'rest'

    def reset(self):
        self.control_state.reset()

    def run_loop(self):
        self.timer.start()

    def stop_loop(self):
        self.timer.cancel()
        self.reset()
        self.stop_walk()
        self.pos.stop()
        self.active = False
        self.send_cmd()
        self.user_stop = True

    def toggle_cmd(self):
        # For toggle commands, they should be sent several times to ensure they
        # are put into effect
        for _ in range(3):
            self.send_cmd()
            time.sleep(1 / MESSAGE_RATE)

    def send_cmd(self):
        cmd = self.control_state.get_state()
        self.cmd_pub.send(cmd)
        try:
            msg = self.cmd_sub.get()
            self.joystick.led_color(**msg["ps4_color"])
        except timeout:
            pass

    def get_sensor_data(self):
        try:
            obj = self.obj_sensors.read()
            pos = self.pos.data
            try:
                cv = self.cv_sub.get()
            except timeout:
                cv = []
        except:
            obj, pos, cv = self._last_sensor_data

        self._last_sensor_data = (obj, pos, cv)
        return obj, pos, cv

    def _step(self):
        js_msg = self.joystick.get_input()

        # Force stop moving
        if js_msg['button_l2']:
            self.user_stop = True
            self.stop_walk()
            return

        # User activate
        if js_msg['button_l1']:
            self.user_stop = False
            self.activate()
            return

        if self.user_stop or not self.active:
            self.reset()
            self.send_cmd()
            self.send_pusher_message()
            return

        if not self.walking:
            self.start_walk()
            return

        self.update_behavior()
        self.send_cmd()
        self.send_pusher_message()

    def update_behavior(self):
        obj, pos, cv = self.get_sensor_data()

        if not any(obj.values()):
            self.turn_stop()

        if any(obj.values()):
            # If object, dodge
            self.state = 'avoid'
            self.dodge(obj)
        elif any([x['bbox_label'] == self.target for x in cv]):
            # if target, chase
            self.state = 'goto'
            self.goto(cv)
        else:
            # if nothing, wander
            self.state = 'meander'
            self.meander()

    def dodge(self, obj):
        '''Takes the object sensor data and adjusts the command to avoid any
        objects
        '''
        if obj['left'] and obj['center']:
            self.move_stop()
            self.turn_right()
        elif (obj['right'] and obj['center']) or obj['center']:
            self.move_stop()
            self.turn_left()
        elif obj['left']:
            self.move_forward(vel=ControllerState.LEFT_ANALOG_Y_MAX / 2)
            self.turn_right()
        elif obj['right']:
            self.move_forward(vel=ControllerState.LEFT_ANALOG_Y_MAX / 2)
            self.turn_left()
        elif not any(obj.values()):
            self.turn_stop()

    def meander(self):
        '''moves forward and makes slight turns left and right to search for a
        target -- eventually, for now just move forward
        '''
        self.current_target = None
        self.move_forward()

    def goto(self, cv):
        '''takes a list of bounding boxes, picks the most likely ball and moves
        toward it
        '''
        tmp = [x for x in cv if x['bbox_label'] == self.target]
        if len(tmp) == 0:
            self.meander()

        conf = np.array([x['bbox_confidence'] for x in tmp])
        idx = np.argmax(conf)
        best = tmp[idx]
        center_x = best['bbox_x'] + best['bbox_w'] / 2
        if center_x < self.SCREEN_MID_X:
            self.turn_left()
        elif center_x > self.SCREEN_MID_X:
            self.turn_right()

        self.move_forward()
        self.current_target = best

    def send_pusher_message(self):
        obj, pos, cv = self.get_sensor_data()
        bbox = self.current_target
        timestamp = time.time()
        if bbox is None:
            bbox = {
                'bbox_x': None,
                'bbox_y': None,
                'bbox_h': None,
                'bbox_w': None,
                'bbox_label': None,
                'bbox_confidence': None
            }

        message = {
            'time': timestamp,
            'x_pos': pos['x'],
            'y_pos': pos['y'],
            'x_vel': pos['x_vel'],
            'y_vel': pos['y_vel'],
            'x_acc': pos['x_acc'],
            'y_acc': pos['y_acc'],
            'yaw': pos['yaw'],
            'yaw_rate': pos['yaw_rate'],
            'left_sensor': obj['left'],
            'center_sensor': obj['center'],
            'right_sensor': obj['right'],
            'state': self.state,
            **bbox
        }

        self.pusher_client.send(message)
    dpadx = values["dpad_right"] - values["dpad_left"]
    dpady = values["dpad_up"] - values["dpad_down"]

    msg = {
        "ly": left_y,
        "lx": left_x,
        "rx": right_x,
        "ry": right_y,
        "L2": L2,
        "R2": R2,
        "R1": R1,
        "L1": L1,
        "dpady": dpady,
        "dpadx": dpadx,
        "x": x,
        "square": square,
        "circle": circle,
        "triangle": triangle,
        "message_rate": MESSAGE_RATE,
    }
    joystick_pub.send(msg)

    try:
        msg = joystick_subcriber.get()
        joystick.led_color(**msg["ps4_color"])
    except timeout:
        pass

    time.sleep(1 / MESSAGE_RATE)
예제 #12
0
                # TODO
                timestamp = 0

                try:
                    x, y = project(msg.latitude, msg.longitude,
                                   correction['lat'], correction['lon'])
                    local = [True, x, y]
                except:
                    local = [False, 0, 0]

                to_send = {
                    "time": timestamp,
                    "lat": msg.latitude,
                    "lon": msg.longitude,
                    "alt": msg.altitude,
                    "sats": msg.num_sats,
                    "qual": msg.gps_qual,
                    "age": msg.age_gps_data,
                    "local": local
                }

                pub_gps.send(to_send)

except KeyboardInterrupt:
    print('closing')
    ser.close()
    raise
except:
    ser.close()
    raise
예제 #13
0
        on_right = (pygame.joystick.Joystick(0).get_button(5))
        on_left = (pygame.joystick.Joystick(0).get_button(4))
        l_trigger = (pygame.joystick.Joystick(0).get_axis(3))

        if on_left or on_right:
            if on_right:
                forward = forward_right
            else:
                forward = forward_left

            slow = 150
            fast = 500
            max_speed = (fast+slow)/2 + l_trigger*(fast-slow)/2
            print(max_speed)
            drive_pub.send({'f':(max_speed*forward),'t':-150*twist})
        else:
            pass
            #without button go into freewheel
            drive_pub.send({'f':0,'t':0})

    if mode.startswith('arm'):
        r_forward  = -(pygame.joystick.Joystick(0).get_axis(5))
        r_side = (pygame.joystick.Joystick(0).get_axis(2))

        l_forward  = -(pygame.joystick.Joystick(0).get_axis(1))
        l_side = (pygame.joystick.Joystick(0).get_axis(0))

        r_shoulder  = (pygame.joystick.Joystick(0).get_button(5))
        l_shoulder  = (pygame.joystick.Joystick(0).get_button(4))
예제 #14
0
class Controller:
    def __init__(self, port=8830, rate=20):
        self.keybinds = {
            "space": self.toggle_trot,
            "v": self.activate,
            "w": self.move_forward,
            "a": self.rotate_left,
            "s": self.move_backward,
            "d": self.rotate_right,
            "q": self.move_left,
            "e": self.move_right,
            "x": self.move
        }

        self.velocity = 1  # Needs tuning
        self.lx = 0
        self.ly = 0
        self.rx = 0
        self.l_alpha = 0.15
        self.r_alpha = 0.3

        self.pub = Publisher(port)
        self.rate = rate
        self.blank_msg = {
            "ly": 0,
            "lx": 0,
            "rx": 0,
            "ry": 0,
            "L2": 0,
            "R2": 0,
            "R1": 0,
            "L1": 0,
            "dpady": 0,
            "dpadx": 0,
            "x": 0,
            "square": 0,
            "circle": 0,
            "triangle": 0,
            "message_rate": self.rate,
        }

        keyboard.on_press(lambda c: self.keypress(c))

        self.active = False
        self.ready = False

        print("Controller initialized")

    def keypress(self, c):
        print("Key pressed: ", c.name)
        if c.name in self.keybinds:
            self.keybinds[c.name]()

    def move(self, lx=0.0, ly=0.0, yaw=0.0):
        msg = self.blank_msg.copy()
        self.lx = self.l_alpha * lx + (1 - self.l_alpha) * self.lx
        msg["lx"] = self.lx

        self.ly = self.l_alpha * ly + (1 - self.l_alpha) * self.ly
        msg["ly"] = self.ly

        self.rx = self.r_alpha * yaw + (1 - self.r_alpha) * self.rx
        msg["rx"] = self.rx

        print(msg)
        self.pub.send(msg)

    def move_forward(self, yaw=0.0):
        self.move(ly=self.velocity, yaw=yaw)

    def move_backward(self, yaw=0.0):
        self.move(ly=-self.velocity, yaw=yaw)

    # Move/rotate left/right might be reversed
    def move_left(self):
        self.move(lx=-self.velocity)

    def move_right(self):
        self.move(lx=self.velocity)

    def rotate_right(self):
        self.move(yaw=self.velocity)

    def rotate_left(self):
        self.move(yaw=-self.velocity)

    def activate(self):
        msg = self.blank_msg.copy()
        msg["L1"] = 1
        self.pub.send(msg)

        self.active = not self.active

    def toggle_trot(self):
        msg = self.blank_msg.copy()
        msg["R1"] = 1
        self.pub.send(msg)

        self.ready = self.active and not self.ready
예제 #15
0
from UDPComms import Publisher
import time
from mpu6050 import mpu6050

pub = Publisher(8004)
sensor = mpu6050(0x68)
sensor.set_gyro_range(mpu6050.GYRO_RANGE_2000DEG)
last_send = time.time()

bias = sensor.get_gyro_data()
while 1:
    now = time.time()
    if (now - last_send >= 0.01):
        accel = sensor.get_accel_data()
        accel_done = time.time()
        gyro = sensor.get_gyro_data()
        gyro_done = time.time()
        gyro = {k: (v - bias[k]) / 180.0 * 3.14159 for k, v in gyro.items()}
        accel = {k: -v for k, v in accel.items()}

        pub.send((accel['x'], accel['y'], accel['z'], gyro['x'], gyro['y'],
                  gyro['z']))

        print('{:<1.3f}\t{:<1.3f}\t{:<1.3f}'.format(gyro['x'], gyro['y'],
                                                    gyro['z']))
        #print('{:1.3f}\t{:1.3f}\t{:1.3f}'.format(accel['x'],accel['y'],accel['z']))
        #print(round(gyro['x'],3), '\t', round(gyro['y'], 3), '\t', round(gyro['z'],3))
        #print(now - last_send, accel_done - now, gyro_done - accel_done)
        last_send = now
예제 #16
0
class Arm:
    def __init__(self):
        GPIO.setmode(GPIO.BCM)
        GPIO.setup(SHOULDER_HOME_INPUT, GPIO.IN, pull_up_down = GPIO.PUD_UP)
        GPIO.setup(ELBOW_HOME_INPUT, GPIO.IN, pull_up_down = GPIO.PUD_UP)
        self.target_vel = Subscriber(8410)

        self.xyz_names = ["x", "y","yaw"]

        self.output_pub = Publisher(8420)

        self.cartesian_motors = ["shoulder","elbow","yaw"]
        self.motor_names = ["shoulder","elbow","yaw","roll","grip"]
        self.pwm_names = ["pitch"]
        self.ordering = ["shoulder","elbow","pitch","yaw","grip","roll"]
        self.native_positions = { motor:0 for motor in self.motor_names}

        self.currents = { motor:0 for motor in self.motor_names}
        self.xyz_positions    = { axis:0 for axis in self.xyz_names}
        self.elbow_left = True

        self.CPR = {'shoulder': -12.08 * 4776.38,
                    'elbow'   : -12.08 * 2442.96,
                    'yaw'     : -float(48)/27 * 34607,
                    'roll'    : 455.185*float(12*53/20),
                    'grip'    : 103.814*float(12*36/27)}
        #            'pitch'   : -2 * 34607}

        self.SPEED_SCALE = 20

        self.rc = RoboClaw(find_serial_port(), names = self.ordering,\
                                                    addresses = [130,128,129])
        self.zeroed = False

        self.storageLoc = [0,0]
	
        self.limits = {'shoulder':[-2.18,2.85],
                       'elbow'   : [-4,2.24], #-2.77
                       'yaw'     : [-3.7,3.7] }

        self.dock_pos = {'shoulder': 2.76,
                         'elbow'   : -2.51,
                         'yaw'     : -3.01 }
        self.dock_speeds = [.01,.006]

        self.forcing = False

        try:
            while 1:
                start_time = time.time()
                self.update()
                while (time.time() - start_time) < 0.1:
                    pass

        except KeyboardInterrupt:
            self.send_speeds( {motor: 0 for motor in self.motor_names}, {motor: 0 for motor in self.pwm_names} )
            raise
        except:
            self.send_speeds( {motor: 0 for motor in self.motor_names}, {motor: 0 for motor in self.pwm_names} )
            raise

    #deadbands & nonlinear controls on speed
    def condition_input(self,target): 
        target['x']     = - target['x']
        if(target['pitch'] > .1):
        	target['pitch'] = -1.23* (target['pitch']-.1)**2
        elif(target['pitch'] < -.1):
                target['pitch'] = 1.23* (target['pitch']+.1)**2
        else:
        	target['pitch'] = 0
        target['grip'] =  .04*target['grip']
        target['roll'] = .01*target['roll']
        target['z'] = - target['z']
        if(target['yaw'] > .1): 
        	target['yaw']  = 0.008* (1.1 * (target['yaw']-.1))**3
        elif(target['yaw'] < -.1): 
        	target['yaw']  = 0.008* (1.1 * (target['yaw']+.1))**3
        else:
        	target['yaw'] = 0
        # rotates command frame to end effector orientation
        angle = self.xyz_positions['yaw']
        x = -target['x']*abs(target['x'])
        y = target['y']*abs(target['y'])
        if(target['trueXYZ'] == 0):
        	target['x'] = x*math.cos(angle) - y*math.sin(angle)
        	target['y'] = x*math.sin(angle) + y*math.cos(angle)

        return target

    #output all speeds to all motors
    def send_speeds(self, speeds, target):
        for motor in self.motor_names:
            print('driving', motor, 'at', int(self.SPEED_SCALE * self.CPR[motor] * speeds[motor]))
            if int(self.SPEED_SCALE * self.CPR[motor] * speeds[motor]) == 0:
                self.rc.drive_duty(motor, 0)
            else:
                self.rc.drive_speed(motor, int(self.SPEED_SCALE * self.CPR[motor] * speeds[motor]))

        for motor in self.pwm_names:
            print('driving pwm', motor, 'at', int(20000*target[motor]))
            self.rc.drive_duty(motor, int(20000*target[motor]))

    #check if motors are homed, get position & currents
    def get_status(self):
        self.forcing = False
        for i,motor in enumerate(self.cartesian_motors):
            encoder = self.rc.read_encoder(motor)[1]
            print(motor,encoder)
            self.native_positions[motor] = 2 * math.pi * encoder/self.CPR[motor]
            self.currents[motor] = self.rc.read_current(motor)
            if(self.currents[motor] > 1.5):
                self.forcing = True

        self.xyz_positions = self.native_to_xyz(self.native_positions)
        print("Current Native: ", self.native_positions)
        print("Current    XYZ: ", self.xyz_positions)

    def xyz_to_native(self, xyz):
        native = {}

        distance = math.sqrt(xyz['x']**2 + xyz['y']**2)
        angle    = -math.atan2(xyz['x'], xyz['y'])

        offset = math.acos( ( FIRST_LINK**2 + distance**2 - SECOND_LINK**2  ) / (2*distance * FIRST_LINK) )
        inside = math.acos( ( FIRST_LINK**2 + SECOND_LINK**2 - distance**2  ) / (2*SECOND_LINK * FIRST_LINK) )

        if self.elbow_left:
            # is in first working configuration
            native['shoulder'] = angle + offset - math.pi
            native['elbow']    = - (math.pi - inside)
        else:
            native['shoulder'] = angle - offset - math.pi
            native['elbow']    = (math.pi - inside)

        native['yaw']   = xyz['yaw'] -native['shoulder']-native['elbow']
#        native['pitch'] = xyz['pitch']

        return native

    def native_to_xyz(self, native):
        xyz = {}
        xyz['x'] = -FIRST_LINK * math.sin(native['shoulder']) - SECOND_LINK * math.sin(native['shoulder'] + native['elbow'])
        xyz['y'] = FIRST_LINK * math.cos(native['shoulder']) + SECOND_LINK * math.cos(native['shoulder'] + native['elbow'])

        xyz['yaw']   = native['yaw']  + (native['shoulder']+native['elbow'])
#        xyz['pitch'] = native['pitch']
        return xyz

    # analytic jacobian of angles -> XYZ
    def dnative(self, dxyz):
        x = self.xyz_positions['x']
        y = self.xyz_positions['y']

        shoulder_diff_x = y/(x**2 + y**2) - (x/(FIRST_LINK*math.sqrt(x**2 + y**2)) - x*(FIRST_LINK**2 - SECOND_LINK**2 + x**2 + y**2)/(2*FIRST_LINK*(x**2 + y**2)**(3/2)))/math.sqrt(1 - (FIRST_LINK**2 - SECOND_LINK**2 + x**2 + y**2)**2/(4*FIRST_LINK**2*(x**2 + y**2)))

        shoulder_diff_y = -x/(x**2 + y**2) - (y/(FIRST_LINK*math.sqrt(x**2 + y**2)) - y*(FIRST_LINK**2 - SECOND_LINK**2 + x**2 + y**2)/(2*FIRST_LINK*(x**2 + y**2)**(3/2)))/math.sqrt(1 - (FIRST_LINK**2 - SECOND_LINK**2 + x**2 + y**2)**2/(4*FIRST_LINK**2*(x**2 + y**2)))

        elbow_diff_x = -x/(FIRST_LINK*SECOND_LINK*math.sqrt(1 - (FIRST_LINK**2 + SECOND_LINK**2 - x**2 - y**2)**2/(4*FIRST_LINK**2*SECOND_LINK**2)))

        elbow_diff_y = -y/(FIRST_LINK*SECOND_LINK*math.sqrt(1 - (FIRST_LINK**2 + SECOND_LINK**2 - x**2 - y**2)**2/(4*FIRST_LINK**2*SECOND_LINK**2)))

        dnative = {}
        dnative['shoulder'] = shoulder_diff_x * dxyz['x'] + shoulder_diff_y * dxyz['y'] 
        dnative['elbow']    = elbow_diff_x    * dxyz['x']    + elbow_diff_y * dxyz['y'] 

        print("Dxyz   : ", dxyz)
        print("Dnative: ", dnative)
        print("new location: ", self.native_to_xyz ( {motor:dnative[motor] + self.native_positions[motor] for motor in self.motor_names}) )
        return dnative

    #numerical jacobian of angles -> XYZ
    def dnative2(self, dxyz):
        h = 0.00000001
       # print dxyz, self.xyz_positions
        x_plus_h = { axis:self.xyz_positions[axis] + h*dxyz[axis] for axis in self.xyz_names}

        f_x_plus_h = self.xyz_to_native(x_plus_h)
        f_x        = self.xyz_to_native(self.xyz_positions)

        dnative = {motor:(f_x_plus_h[motor] - f_x[motor])/h for motor in self.cartesian_motors}

        print("Dxyz   : ", dxyz)
        print("Dnative: ", dnative)
        print("new location: ", self.native_to_xyz ( {motor:dnative[motor] + f_x[motor] for motor in self.cartesian_motors}) )
        return dnative

    def sign(self,val):
        return int(val > 0) - int(val < 0)

    #prevent movement near singularity or if the motor is out of bounds or at home
    def check_in_bounds(self, speeds):
        inBounds = True 
        
        if(abs(self.native_positions['elbow']) < .4):
            if(self.native_positions['elbow'] < 0 and self.sign(speeds['elbow']) == 1):
                inBounds = False
                print("SINGULARITY")
            elif(self.native_positions['elbow'] > 0 and self.sign(speeds['elbow']) == -1):
                inBounds = False
                print("SINGULARITY")
        for motor in self.cartesian_motors:
            if(self.sign(speeds[motor]) == -1):
                if(self.native_positions[motor] < self.limits[motor][0]):
                    inBounds = False
            elif(self.native_positions[motor] > self.limits[motor][1]):
                inBounds = False
        if(not inBounds):
            for motor in self.cartesian_motors:
               speeds[motor] = 0
        return speeds

    def check_limits(self, speeds):
        inBounds = True 
        if(GPIO.input(SHOULDER_HOME_INPUT) and self.sign(speeds['elbow']) == 1):
            self.rc.set_encoder('shoulder',SHOULDER_HOME)
            inBounds = False

        if(GPIO.input(ELBOW_HOME_INPUT) and self.sign(speeds['elbow']) == -1):
            self.rc.set_encoder('elbow',ELBOW_HOME*self.cpr['elbow'])
            inBounds = False
        if(not inBounds):
            for motor in self.cartesian_motors:
               speeds[motor] = 0
        return speeds

    #return to our docking position
    def dock(self,speeds):
        if(abs(self.native_positions['yaw']-self.dock_pos['yaw']-.03)>.01):
            speeds['shoulder'] = 0
            speeds['elbow'] = 0
            speeds['yaw'] = self.dock_speed(self.native_positions['yaw'],self.dock_pos['yaw']+.03,self.dock_speeds[0],self.dock_speeds[1])
        elif(abs(self.native_positions['elbow']-self.dock_pos['elbow']+.03)>.01):
            speeds['shoulder'] = 0
            speeds['elbow'] = self.dock_speed(self.native_positions['elbow'],self.dock_pos['elbow']-.03,self.dock_speeds[0],self.dock_speeds[1])
            speeds['yaw'] = 0
        elif(abs(self.native_positions['shoulder']-self.dock_pos['shoulder']-.03)>.01):
            speeds['shoulder'] = self.dock_speed(self.native_positions['shoulder'],self.dock_pos['shoulder']+.03,self.dock_speeds[0],self.dock_speeds[1])
            speeds['elbow'] = 0
            speeds['yaw'] = 0
        return speeds


    #PID for docking speed
    def dock_speed(self,curPos,desiredPos,P,maxV):
        dir = self.sign(desiredPos-curPos)
        output = abs(curPos-desiredPos)*P+.0005
        if(output > maxV):
            output = maxV
        return output*dir

    def update(self):
        print()
        print("new iteration")
        self.get_status()
        output = {}
        print("read status of shoulder", GPIO.input(20))
        for d in (self.native_positions,self.xyz_positions): 
            output.update(d)
        #print("HOME STATUS ", self.home_status)
        #output.update({"shoulder limit", self.home_status["shoulder"]})
        output.update({"forcing":self.forcing})
        self.output_pub.send(output)
        try:
            target = self.target_vel.get()
            # TODO: This shouldn't be necessary, how to fix in UDPComms?
            target = {bytes(key): value for key, value in target.iteritems()}

            target_f = self.condition_input(target)
            speeds = self.dnative2(target_f) 
            if(not self.zeroed):
                speeds['elbow'] = 0
                speeds['shoulder'] = 0
            speeds = self.check_in_bounds(speeds)
            speeds['elbow'] -= 0.002 * target_f['hat'][0]
            speeds['shoulder'] -= 0.002 * target_f['hat'][1]
            speeds['yaw'] += target_f['yaw']
            speeds['roll'] = target_f['roll']
            speeds['grip'] = target_f['grip'] + speeds['roll']
            speeds = self.check_limits(speeds)
            if speeds['elbow'] == 0 and speeds['shoulder'] == 0:
                self.elbow_left = self.native_positions['elbow'] < 0

            if(target_f['dock']):
                speeds=self.dock(speeds)
	   
            if target_f["reset"]:
                print ("RESETTING!!!")
                self.zeroed = True
                speeds = {motor: 0 for motor in self.motor_names}
                target_f = {motor: 0 for motor in self.pwm_names}
                self.send_speeds(speeds, target_f)
                self.rc.set_encoder("shoulder",0)
                self.rc.set_encoder("elbow",0)
                self.rc.set_encoder("yaw",0)

            elif target_f["resetdock"]:
                print ("RESETTING (in dock position)!!!")
                self.zeroed = True
                speeds = {motor: 0 for motor in self.motor_names}
                target_f = {motor: 0 for motor in self.pwm_names}
                self.send_speeds(speeds, target_f)
                self.rc.set_encoder("shoulder",int(self.CPR["shoulder"]*self.dock_pos['shoulder']/6.28))
                self.rc.set_encoder("elbow",int(self.CPR["elbow"]*self.dock_pos['elbow']/6.28))
                self.rc.set_encoder("yaw",int(self.CPR["yaw"]*self.dock_pos['yaw']/6.28))

        except timeout:
            print ("TIMEOUT No commands recived")
            speeds = {motor: 0 for motor in self.motor_names}
            target_f = {}
            target_f = {motor: 0 for motor in self.pwm_names}
        except ValueError:
            print ("ValueError The math failed")
            speeds = {motor: 0 for motor in self.motor_names}

            speeds['elbow'] -= 0.002 * target_f['hat'][0]
            speeds['shoulder'] -= 0.002 * target_f['hat'][1]
        except:
            speeds = {motor: 0 for motor in self.motor_names}
            target_f = {motor: 0 for motor in self.pwm_names}
            raise
        finally:
            print ("SPEEDS"), speeds, target_f
            self.send_speeds(speeds, target_f)
예제 #17
0
    try:
        lidar = rplidar.RPLidar(port)
        break
    except rplidar.RPLidarException:
        pass
else:
    raise rplidar.RPLidarException(
        "Can't find serial port to connect to sensor")


def signal_term_handler(signal, frame):
    lidar.stop()
    lidar.stop_motor()
    exit()


signal.signal(signal.SIGTERM, signal_term_handler)

try:
    for scan in lidar.iter_scans(
            scan_type="express" if use_express else "normal"):
        pub.send(scan)
        print('sending')
    print("end")
except:
    raise
    pass
finally:

    signal_term_handler(None, None)
예제 #18
0
class Simualtor:
    def __init__(self):
        self.master = tk.Tk()

        self.PIX_per_M = 50
        self.canvas = tk.Canvas(self.master, width=400, height=400)
        self.canvas.pack()

        self.robot = Robot(200, 200, self.canvas)

        self.master.bind('<Left>', lambda e: self.robot.move(0, 0.1))
        self.master.bind('<Right>', lambda e: self.robot.move(0, -0.1))
        self.master.bind('<Up>', lambda e: self.robot.move(1, -0))
        self.master.bind('<Down>', lambda e: self.robot.move(-1, -0))

        self.canvas.bind('<Button-1>', self.mouse_draw_down)
        self.canvas.bind('<B1-Motion>', self.mouse_draw_move)
        self.canvas.bind('<ButtonRelease-1>', self.mouse_draw_up)
        self.canvas.bind('<Button-2>', self.mouse_delete)

        self.obstacles = []
        self.mouse_mode = None

        self.scan_points = []
        self.lidar = Publisher(8110)
        self.odom = Publisher(8810)  # publishes twist not wheel rotations

        self.master.after(1000, self.scan)
        self.master.after(100, self.odom_pub)
        tk.mainloop()

    def mouse_draw_down(self, event):
        self.mouse_mode = self.canvas.create_line(event.x, event.y, event.x,
                                                  event.y)

    def mouse_draw_move(self, event):
        if self.mouse_mode != None:
            coords = self.canvas.coords(self.mouse_mode)
            self.canvas.coords(self.mouse_mode, coords[0], coords[1], event.x,
                               event.y)

    def mouse_draw_up(self, event):
        if self.mouse_mode != None:
            coords = self.canvas.coords(self.mouse_mode)
            self.canvas.coords(self.mouse_mode, coords[0], coords[1], event.x,
                               event.y)
            self.obstacles.append(self.mouse_mode)
        self.mouse_mode = None

    def mouse_delete(self, event):
        obj, = self.canvas.find_closest(event.x, event.y)
        if obj in self.obstacles:
            self.canvas.delete(obj)

    def odom_pub(self):
        out = self.robot.get_odom()
        self.odom.send(
            {"single": {
                "odom": (out[1], 1000 * out[0] / self.PIX_per_M)
            }})
        self.master.after(100, self.odom_pub)

    def scan(self):
        coords = [self.canvas.coords(obj) for obj in self.obstacles]
        output = []

        for s in self.scan_points:
            self.canvas.delete(s)

        start = 20
        end = 300

        step = 50

        for angle in np.linspace(0, 2 * np.pi, step):
            s = np.sin(angle)
            c = np.cos(angle)

            x = self.robot.x - s * start
            y = self.robot.y + c * start

            for dist in range(start, end):
                x -= s
                y += c
                items = self.canvas.find_overlapping(x, y, x + 2, y + 2)
                if len(items) != 0:
                    output.append((0, np.degrees(angle + self.robot.a),
                                   1000 * dist / self.PIX_per_M))
                    self.scan_points.append(
                        self.canvas.create_line(x, y, x + 1, y, fill='red'))
                    break

        print(output)
        self.lidar.send(output)
        self.master.after(500, self.scan)
예제 #19
0
class CommandPannel:

    fields = "forward twist"
    typ = "ff"
    port = 8830

    def __init__(self):
        self.root = tk.Tk()

        self.fd = tk.Button(self.root, text='Forwards', command=self.ha)
        self.bk = tk.Button(self.root, text='Back', command=self.ha)
        self.rt = tk.Button(self.root, text='Right', command=self.ha)
        self.lt = tk.Button(self.root, text='Left', command=self.ha)

        self.fd.pack()
        self.bk.pack()
        self.rt.pack()
        self.lt.pack()

        self.root.bind('<Left>', lambda x: self.leftKey(x))
        self.root.bind('<Right>', lambda x: self.rightKey(x))
        self.root.bind('<Up>', lambda x: self.upKey(x))
        self.root.bind('<Down>', lambda x: self.downKey(x))
        self.root.bind('<space>', lambda x: self.spaceKey(x))

        self.speed = 140
        self.forwards = 0
        self.twist = 0
        self.time = time.time()

        # Publisher.broadcast_ip = "<broadcast>"
        self.pub = Publisher(self.fields, self.typ, self.port)

        self.root.after(100, self.publish)
        self.root.mainloop()

    @staticmethod
    def ha():
        print "ha"

    def spaceKey(self, event):
        print "space"
        self.forwards = 0
        self.twist = 0
        self.time = time.time()

    def leftKey(self, event):
        print "left"
        self.forwards = 0
        self.twist = self.speed
        self.time = time.time()

    def rightKey(self, event):
        print "right"
        self.forwards = 0
        self.twist = -self.speed
        self.time = time.time()

    def upKey(self, event):
        print "up"
        self.forwards = self.speed
        self.twist = 0
        self.time = time.time()

    def downKey(self, event):
        print "down"
        self.forwards = -self.speed
        self.twist = 0
        self.time = time.time()

    def publish(self):
        if (time.time() - self.time) > 1:
            self.forwards = 0
            self.twist = 0
        self.pub.send(self.forwards, self.twist)
        print "magic"
        self.root.after(100, self.publish)
예제 #20
0
class Pursuit:
    def __init__(self):

        self.imu = Subscriber(8220, timeout=1)
        self.gps = Subscriber(8280, timeout=2)
        self.auto_control = Subscriber(8310, timeout=5)

        self.cmd_vel = Publisher(8830)
        # self.lights = Publisher(8590)
        self.servo = Publisher(8120)

        self.aruco = Subscriber(8390, timeout=2)
        time.sleep(3)

        self.start_point = {
            "lat": self.gps.get()['lat'],
            "lon": self.gps.get()['lon']
        }
        self.lookahead_radius = 6
        self.final_radius = 1.5  # how close should we need to get to last endpoint
        self.search_radius = 20  # how far should we look from the given endpoint
        self.reached_destination = False  # switch modes into tennis ball seach
        self.robot = None
        self.guess = None  # where are we driving towards
        self.guess_radius = 3  # if we are within this distance we move onto the next guess
        self.guess_time = None

        self.last_tennis_ball = 0

        self.past_locations = []
        self.stuck_time = 0

        while True:
            self.update()
            time.sleep(0.1)

    def get_guess(self, endpoint):
        x, y = endpoint
        rand_x = (2 * random.random() - 1) * self.search_radius
        rand_y = (2 * random.random() - 1) * self.search_radius
        self.random_corrd = (rand_x, rand_y)
        print(rand_x, rand_y)
        return (x + rand_x, y + rand_y)

    def find_ball(self, cmd):
        if cmd['end_mode'] == 'none':
            print("REACHED ENDPOINT")
            # self.lights.send({'r':0, 'g':1, 'b':0})
            self.servo.send({'pan': 0, 'tilt': 90})
            self.send_stop()

        elif cmd['end_mode'] == 'tennis':
            print("Entering search program")

            try:
                marker = self.aruco.get()
            except timeout:
                marker = None

            last_waypoint = cmd['waypoints'][-1]
            endpoint = self.project(last_waypoint['lat'], last_waypoint['lon'])

            if marker == None:

                if (time.time() - self.last_tennis_ball) < 2:
                    # if we saw a ball in the last 2 sec
                    out = {"f": 70, "t": 0}
                    print('cont to prev seen marker', out)
                    self.cmd_vel.send(out)

                else:

                    if self.guess == None:
                        self.guess = self.get_guess(endpoint)
                        self.guess_time = time.time()
                        print("NEW RANDOM GUESS - first")

                    elif self.distance(self.guess) < self.guess_radius:
                        self.guess = self.get_guess(endpoint)
                        print("NEW RANDOM GUESS - next")
                        self.guess_time = time.time()

                    elif (time.time() - self.guess_time) > 40:
                        self.guess = self.get_guess(endpoint)
                        print("NEW RANDOM GUESS - timeout")
                        self.guess_time = time.time()
                        self.guess = self.get_guess(endpoint)

                    print("random corrds", self.random_corrd)
                    diff_angle = self.get_angle(self.guess)
                    self.send_velocities(diff_angle)
            else:
                # self.guess_time = time.time() # will this matter?
                self.last_tennis_ball = time.time()

                if marker['dist'] < 1.5:
                    print("REACHED MARKER")
                    self.send_stop()
                else:
                    self.send_velocities_slow(marker['angle'])

        else:
            print("incorrect mode")

    def update(self):

        try:
            self.robot = self.gps.get()
            cmd = self.auto_control.get()
        except:
            print('lost control')
            return

        if cmd['command'] == 'off':
            print("off")
            self.reached_destination = False
            self.start_point['lat'] = self.gps.get()['lat']
            self.start_point['lon'] = self.gps.get()['lon']
            # self.lights.send({'r':1, 'g':0, 'b':0})
            self.servo.send({'pan': 0, 'tilt': -90})
        elif (cmd['command'] == 'auto'):
            last_waypoint = cmd['waypoints'][-1]

            if self.reached_destination:
                self.find_ball(cmd)

            elif( self.distance(self.project(last_waypoint['lat'], last_waypoint['lon'])) \
                    < self.final_radius ):
                self.reached_destination = True
                print("REACHED final End point")
            elif self.analyze_stuck():
                self.un_stick()
            else:
                lookahead = self.find_lookahead(cmd['waypoints'])
                diff_angle = self.get_angle(lookahead)
                self.send_velocities(diff_angle)
        else:
            raise ValueError

    def analyze_stuck(self):
        self.past_locations.append([
            self.project(self.robot['lat'], self.robot['lon']),
            self.imu.get()['angle'][0],
            time.time()
        ])
        if len(self.past_locations) < 100:
            return False

        while len(self.past_locations) > 100:
            self.past_locations.pop(0)
        if (time.time() - self.stuck_time < 14):
            return False

        abs_angle = lambda x, y: min(abs(x - y + i * 360) for i in [-1, 0, 1])
        # location, t = self.past_locations[0]
        # if self.distance(location)/(time.time() - t) < 0.1
        locations = [self.past_locations[10 * i + 5][0] for i in range(9)]
        angles = [self.past_locations[10 * i + 5][1] for i in range(9)]

        max_loc = max([self.distance(loc) for loc in locations])
        max_angle = max(
            [abs_angle(ang,
                       self.imu.get()['angle'][0]) for ang in angles])

        print("we are", max_loc, "from stcuk and angle", max_angle)

        if max_loc < 1 and max_angle < 30:
            print("WE ARE STUCK")
            # self.stuck_location = location
            self.stuck_time = time.time()
            return True
        return False

    def un_stick(self):
        start_time = time.time()
        while (time.time() - start_time) < 4 and self.auto_control.get(
        )['command'] == 'auto':
            self.analyze_stuck()
            out = {"f": -100, "t": -20}
            print('unsticking', out)
            self.cmd_vel.send(out)
            time.sleep(0.1)

        start_time = time.time()
        start_angle = self.imu.get()['angle'][0]
        while (time.time() - start_time) < 1 and self.auto_control.get(
        )['command'] == 'auto':
            self.analyze_stuck()
            out = {"f": 0, "t": -70}
            print('unsticking part 2', out)
            self.cmd_vel.send(out)
            time.sleep(0.1)

        start_time = time.time()
        while (time.time() - start_time) < 2 and self.auto_control.get(
        )['command'] == 'auto':
            self.analyze_stuck()
            out = {"f": 70, "t": 0}
            print('unsticking part 2', out)
            self.cmd_vel.send(out)
            time.sleep(0.1)

    def find_lookahead(self, waypoints):
        start_waypoints = [self.start_point] + waypoints
        waypoint_pairs = zip(start_waypoints[::-1][1:],
                             start_waypoints[::-1][:-1])
        i = 0
        for p1, p2 in waypoint_pairs:
            lookahead = self.lookahead_line(p1, p2)
            if lookahead is not None:
                print("point intersection", i)
                return lookahead
            i += 1
        else:
            print("NO intersection found!")

        distances = []
        for p1, p2 in waypoint_pairs:
            lookahead = self.lookahead_line(p1, p2, project=True)
            if lookahead is not None:
                distances.append((self.distance(lookahead), lookahead))

        for p1 in waypoints:
            point = self.project(p1['lat'], p1['lon'])
            distances.append((self.distance(point), point))

        return min(distances)[1]

    def distance(self, p1):
        x_start, y_start = p1
        # self.robot = self.gps.get()
        x_robot, y_robot = self.project(self.robot['lat'], self.robot['lon'])
        return math.sqrt((x_start - x_robot)**2 + (y_start - y_robot)**2)

    def lookahead_line(self, p1, p2, project=False):
        x_start, y_start = self.project(p1['lat'], p1['lon'])
        x_end, y_end = self.project(p2['lat'], p2['lon'])

        # self.robot = self.gps.get()
        x_robot, y_robot = self.project(self.robot['lat'], self.robot['lon'])

        if (x_robot - x_end)**2 + (y_robot -
                                   y_end)**2 < self.lookahead_radius**2:
            return (x_end, y_end)

        a = (x_end - x_start)**2 + (y_end - y_start)**2
        b = 2 * ((x_end - x_start) * (x_start - x_robot) + (y_end - y_start) *
                 (y_start - y_robot))
        c = (x_start - x_robot)**2 + (y_start -
                                      y_robot)**2 - self.lookahead_radius**2

        if b**2 - 4 * a * c <= 0:
            if project:
                t = -b / (2 * a)
            else:
                return None
        else:
            t = (-b + math.sqrt(b**2 - 4 * a * c)) / (2 * a)

        if not t <= 1:
            return None
        if not t >= 0:
            return None

        x_look = t * x_end + (1 - t) * x_start
        y_look = t * y_end + (1 - t) * y_start

        return (x_look, y_look)

    def get_angle(self, lookahead):
        heading_deg = self.imu.get()['angle'][0]
        head_rad = math.radians(heading_deg)

        x_robot, y_robot = self.project(self.robot['lat'], self.robot['lon'])
        x_look, y_look = lookahead

        target = math.atan2(x_look - x_robot, y_look - y_robot)

        # anti clockwise positive
        return ((target - head_rad + math.pi) % (2 * math.pi) - math.pi)

    def send_velocities_slow(self, angle):
        # turn_rate = -100*math.tanh(1*angle)
        turn_rate = -200 * angle / math.pi

        if math.fabs(angle) < math.radians(10):
            forward_rate = 90
        elif math.fabs(angle) < math.radians(60):
            forward_rate = 50
        elif math.fabs(angle) < math.radians(140):
            forward_rate = 30
        else:
            forward_rate = 0

        out = {"f": forward_rate, "t": turn_rate}

        # out = {"f": 70, "t": -150*angle/math.pi }
        print(out)
        self.cmd_vel.send(out)

    def send_velocities(self, angle):
        # turn_rate = -100*math.tanh(1*angle)
        turn_rate = -200 * angle / math.pi

        if math.fabs(angle) < math.radians(10):
            forward_rate = 130
        elif math.fabs(angle) < math.radians(60):
            forward_rate = 80
        elif math.fabs(angle) < math.radians(140):
            forward_rate = 30
        else:
            forward_rate = 0

        out = {"f": forward_rate, "t": turn_rate}

        # out = {"f": 70, "t": -150*angle/math.pi }
        print(out)
        self.cmd_vel.send(out)

    def send_stop(self):
        out = {"f": 0, "t": 0}
        # out = {"f": 70, "t": -150*angle/math.pi }
        print('stoping', out)
        self.cmd_vel.send(out)

    def project(self, lat, lon):
        lat_orig = self.start_point['lat']
        lon_orig = self.start_point['lon']
        RADIUS = 6371 * 1000
        lon_per_deg = RADIUS * 2 * math.pi / 360
        lat_per_deg = lon_per_deg * math.cos(math.radians(lat_orig))

        x = (lon - lon_orig) * lon_per_deg
        y = (lat - lat_orig) * lat_per_deg
        return (x, y)
while 1:
    try:
        pygame.joystick.Joystick(0).init()
        break
    except pygame.error:
        pygame.time.wait(500)

# Prints the joystick's name
JoyName = pygame.joystick.Joystick(0).get_name()
print("Name of the joystick:")
print(JoyName)
# Gets the number of axes
JoyAx = pygame.joystick.Joystick(0).get_numaxes()
print("Number of axis:")
print(JoyAx)

while True:
    pygame.event.pump()

    forward = (pygame.joystick.Joystick(0).get_axis(3))
    twist = (pygame.joystick.Joystick(0).get_axis(2))
    on = (pygame.joystick.Joystick(0).get_button(5))

    if on:
        print({'f': -150 * forward, 't': -80 * twist})
        drive_pub.send({'f': -150 * forward, 't': -80 * twist})
    else:
        drive_pub.send({'f': 0, 't': 0})

    pygame.time.wait(100)
        on_left = values['button_l1']
        l_trigger = values['l2_analog']

        if on_left or on_right:
            if on_right:
                forward = forward_right
            else:
                forward = forward_left

            slow = 150
            fast = 500

            max_speed = (fast+slow)/2 + l_trigger*(fast-slow)/2

            out = {'f':(max_speed*forward),'t':-150*twist}
            drive_pub.send(out)
            print(out)
        else:
            drive_pub.send({'f':0,'t':0})

    elif mode == MODES.ARM:
        r_forward  = - values['right_analog_y']
        r_side = values['right_analog_x']

        l_forward  = - values['left_analog_y']
        l_side = values['left_analog_x']

        r_shoulder  = values['button_r1']
        l_shoulder  = values['button_l1']

        r_trigger  = values['r2_analog']
예제 #23
0
    motor_vels[3] = middle_odrive.axis0.encoder.vel_estimate
    motor_vels[4] = back_odrive.axis1.encoder.vel_estimate
    motor_vels[5] = back_odrive.axis0.encoder.vel_estimate
    return motor_currents, motor_vels


while True:
    try:
        msg = cmd.get()
        #        print(msg)
        #        print(control_state)
        currents, vels = get_data(front_odrive, middle_odrive, back_odrive)
        print(currents)
        #       print("measured:", front_odrive.axis0.motor.current_control.Iq_measured)
        try:
            telemetry.send([middle_odrive.vbus_voltage] + currents)
        except:
            pass

        clear_errors(front_odrive)
        clear_errors(middle_odrive)
        clear_errors(back_odrive)

        if (msg['cur'] == 1):
            #            print ("switching")
            control_state = 2
            stalled_motor = 6
        if (msg['vel'] == 1):
            control_state = 1

        if (msg['t'] == 0 and msg['f'] == 0):
class Rover:
    def __init__(self):
        self.imu = Subscriber(8220, timeout=2)
        self.gps = Subscriber(8280, timeout=3)
        self.auto_control = Subscriber(8310, timeout=5)
        self.lights = Publisher(8311)

        self.cmd_vel = Publisher(8830)

        self.logger = Logger(8312)

        self.aruco = Subscriber(8390, timeout=3)

        time.sleep(2)  # delay to give extra time for gps message
        self.start_gps = self.gps.recv()

        self.cmd_sent = False

    def project(self, lat, lon):
        lat_orig = self.start_gps['lat']
        lon_orig = self.start_gps['lon']
        RADIUS = 6371 * 1000
        lon_per_deg = RADIUS * 2 * math.pi / 360
        lat_per_deg = lon_per_deg * math.cos(math.radians(lat_orig))

        x = (lon - lon_orig) * lon_per_deg
        y = (lat - lat_orig) * lat_per_deg
        return (x, y)

    def get_pose(self):
        gps = self.gps.get()
        # heading = math.radians( 360 -self.imu.get()['angle'][0] )
        heading = math.radians(self.imu.get()['angle'][0])
        return Pose(*self.project(gps['lat'], gps['lon']), heading)

    def send_vel(self, forward, twist):
        msg = {"f": forward, "t": twist}
        if self.cmd_sent:
            print("ERROR Multiple commands being sent!")
        self.cmd_vel.send(msg)
        self.cmd_sent = True
        print(msg)

    def get_aruco(self):
        markers = self.aruco.get()
        out = {}
        for marker in markers:
            idx, dist, angle = marker['id'], marker['dist'], marker['angle']
            out[idx] = Bearing(dist, math.radians(angle))
        return out

    def get_cmd(self):
        return self.auto_control.get()

    def get_waypoints(self) -> List["Pose"]:
        wps = self.auto_control.get()['waypoints']
        out = []
        for waypoint in wps:
            out.append(Pose(*self.project(waypoint['lat'], waypoint['lon'])))
        return out

    def next_iteration(self):
        self.cmd_sent = False
        self.logger.next()
예제 #25
0
        print "responce closed"
        break
    buf += response.read(100)
    length = get_length(buf)
    next_header = buf[length:].find(chr(0xd3))
    # print(length,next_header, len(buf), len(msgs))
    # print buf[length: length + next_header].encode("hex")
    if (next_header == -1):
        print "no header found"
        continue
    msgs.append(buf[:length + next_header])
    buf = buf[length + next_header:]

    if (time.time() - last_message) > publish_interval:
        rtcm = "".join(msgs)
        print(len("".join(msgs)))
        msgs = []
        last_message = time.time()

        # timestamp = (msg.timestamp - datetime(1970, 1, 1)).total_seconds()
        to_send = {
            "time": 0,
            "lat": 37.41652,
            "lon": -122.20427,
            "alt": 64,
            "sats": 0,
            "rtcm": rtcm
        }

        pub.send(to_send)
예제 #26
0
            )
        else:
            key = pygame.key.get_pressed()
            msg = {}
            msg["lx"] = 0.75 * direction_helper(key[pygame.K_a],
                                                key[pygame.K_d])
            msg["ly"] = 0.75 * direction_helper(key[pygame.K_s],
                                                key[pygame.K_w])
            msg["rx"] = 0.75 * direction_helper(key[pygame.K_LEFT],
                                                key[pygame.K_RIGHT])
            msg["ry"] = 0.75 * direction_helper(key[pygame.K_DOWN],
                                                key[pygame.K_UP])
            msg["x"] = 1 if key[pygame.K_x] else 0
            msg["square"] = 1 if key[pygame.K_u] else 0
            msg["circle"] = 1 if key[pygame.K_c] else 0
            msg["triangle"] = 1 if key[pygame.K_t] else 0
            msg["dpady"] = 1.0 * direction_helper(key[pygame.K_k],
                                                  key[pygame.K_i])
            msg["dpadx"] = 1.0 * direction_helper(key[pygame.K_j],
                                                  key[pygame.K_l])
            msg["L1"] = 1 if key[pygame.K_q] else 0
            msg["R1"] = 1 if key[pygame.K_e] else 0
            msg["L2"] = 0
            msg["R2"] = 0
            msg["message_rate"] = MESSAGE_RATE
            print(msg)

        pub.send(msg)
        pygame.display.flip()
        pygame.time.wait(int(1000 / MESSAGE_RATE))
예제 #27
0
    # bias = dictvec_to_array(sensor.get_gyro_data())
    bias = np.zeros(3)

    np.set_printoptions(suppress=True, precision=3)
    while 1:
        now = time.time()

        if now - last_update > DT:
            gyro_data = sensor.get_gyro_data()
            accel_data = sensor.get_accel_data()
            gyro_data, accel_data = clean_sensor_data(gyro_data, accel_data,
                                                      bias)

            filt_comp.update_gyro(gyro_data, DT)
            filt_comp.update_acel(accel_data)

            filt_mekf.update_gyro(gyro_data, DT)
            filt_mekf.update_acel(accel_data)

            comp_pub.send(list(filt_comp.quat().q))
            mekf_pub.send(list(filt_mekf.quat().q))
            raw_sensor_pub.send((list(gyro_data), list(accel_data)))

            if t % 10 == 0:
                print("dt: {:1.3f} gyro: {} q: {}".format(
                    now - last_update, gyro_data, filt_comp.quat()))

            last_update = now
            t += 1
        square  = (pygame.joystick.Joystick(0).get_button(0))
        cross  = (pygame.joystick.Joystick(0).get_button(1))
        circle  = (pygame.joystick.Joystick(0).get_button(2))
        triangle  = (pygame.joystick.Joystick(0).get_button(3))
        forward = 0
        turn = 0
        if on_left:
            forward = -forward_left
            turn = twist
        elif on_right:
            forward = -forward_right
            turn = twist
        vel = 1 if r_trigger > .5 else 0
        cur = 1 if l_trigger > .5 else 0
        drive_pub.send({'f':forward,'t':turn, 'power_left':square, 'power_back':cross, 'power_right':circle, 'power_mid': triangle,'vel':vel,'cur':cur})
        print({'f':forward,'t':turn, 'power_left':square, 'power_back':cross, 'power_right':circle, 'power_mid': triangle,'vel':vel,'cur':cur})
   
    if mode.startswith('arm'):
        r_forward  = -(pygame.joystick.Joystick(0).get_axis(5))
        r_side = (pygame.joystick.Joystick(0).get_axis(2))

        l_forward  = -(pygame.joystick.Joystick(0).get_axis(1))
        l_side = (pygame.joystick.Joystick(0).get_axis(0))

        r_shoulder  = (pygame.joystick.Joystick(0).get_button(5))
        l_shoulder  = (pygame.joystick.Joystick(0).get_button(4))

        r_trigger  = (pygame.joystick.Joystick(0).get_axis(4))
        l_trigger = (pygame.joystick.Joystick(0).get_axis(3))
예제 #29
0
compass = HMC6343()

# initialize filter
# TODO find good value
filt = ComplementaryFilter(0.99)

lastGyro = 0
lastMag = 0
lastPub = 0

while True:
    if time() - lastMag > 0.10:
        heading = compass.readHeading()
        filt.update_mag(heading)
        lastMag = time()

    if time() - lastGyro > 0.01:
        gyro_x, gyro_y, gyro_z = imu.gyro
        filt.update_gyro(-gyro_z)
        lastGyro = time()

    if time() - lastPub > 0.05:
        try:
            offset = float(offset_sub.get())
        except:
            pass
        angle = filt.get_angle() + offset
        print(angle, heading, filt.lastGyro)
        pub.send({'angle': [angle, None, None], 'mag': heading + offset})
        lastPub = time()
class PTZPannel:
    def __init__(self):
        self.pub = Publisher(8120)
        self.root = tk.Tk()

        self.fd = tk.Button(self.root,
                            text='Up',
                            command=lambda: self.upKey(None))
        self.bk = tk.Button(self.root,
                            text='Down',
                            command=lambda: self.downKey(None))
        self.rt = tk.Button(self.root,
                            text='Right',
                            command=lambda: self.rightKey(None))
        self.lt = tk.Button(self.root,
                            text='Left',
                            command=lambda: self.leftKey(None))
        self.cam2 = tk.Button(self.root,
                              text='POV',
                              command=lambda: self.launchCam('camera2'))
        self.cam3 = tk.Button(self.root,
                              text='Side',
                              command=lambda: self.launchCam('camera3'))
        self.ptz = tk.Button(self.root,
                             text='PTZ',
                             command=lambda: self.launchCam('ptz'))
        self.drive = tk.Button(self.root,
                               text='drive',
                               command=lambda: self.launchCam('drive'))

        self.fd.pack()
        self.bk.pack()
        self.rt.pack()
        self.lt.pack()
        self.cam2.pack()
        self.cam3.pack()
        self.ptz.pack()
        self.drive.pack()

        self.root.bind('<Left>', lambda x: self.leftKey(x))
        self.root.bind('<Right>', lambda x: self.rightKey(x))
        self.root.bind('<Up>', lambda x: self.upKey(x))
        self.root.bind('<Down>', lambda x: self.downKey(x))
        self.root.bind('<space>', lambda x: self.spaceKey(x))

        self.pan = 0
        self.tilt = 0

        self.speed = 2
        self.time = time.time()

        self.root.after(100, self.update)
        self.root.mainloop()

    def launchCam(self, cam):
        os.system("bash launch_camera.sh " + cam + ".local")

    def spaceKey(self, event):
        print "space"
        self.pan = 0
        self.tilt = 0
        self.time = time.time()

    def leftKey(self, event):
        print "left"
        self.pan = -self.speed
        self.tilt = 0
        self.time = time.time()

    def rightKey(self, event):
        print "right"
        self.pan = self.speed
        self.tilt = 0
        self.time = time.time()

    def upKey(self, event):
        print "up"
        self.pan = 0
        self.tilt = -self.speed
        self.time = time.time()

    def downKey(self, event):
        print "down"
        self.pan = 0
        self.tilt = self.speed
        self.time = time.time()

    def update(self):
        print('update')
        try:
            if (time.time() - self.time) > 0.3:
                self.pan = 0
                self.tilt = 0
            print('sending')
            self.pub.send({'pan': self.pan, 'tilt': self.tilt})
        except:
            raise
        finally:
            self.root.after(100, self.update)