Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Creating Crazy Robotic Librarians

Creating Crazy Robotic Librarians

Avatar for Marwan Alsabbagh

Marwan Alsabbagh

May 26, 2019
Tweet

More Decks by Marwan Alsabbagh

Other Decks in Programming

Transcript

  1. Crickit API >>> from adafruit_crickit import crickit >>> # DC

    motor 1 full speed, half speed, off, reverse >>> crickit.dc_motor_1.throttle = 1 >>> crickit.dc_motor_1.throttle = 0.5 >>> crickit.dc_motor_1.throttle = 0 >>> crickit.dc_motor_1.throttle = -1 >>> # servo configure, set angle to 0 and 90 degrees >>> crickit.servo_1.actuation_range = 140 >>> crickit.servo_1.angle = 0 >>> crickit.servo_1.angle = 90 >>> # check state of capacitive touch >>> crickit.touch_1.value False
  2. Teach API >>> from teach import r >>> # DC

    motor 1 full speed, half speed, off, reverse >>> r.wheel = 1 >>> r.wheel = 0.5 >>> r.wheel = 0 >>> r.wheel = -1 >>> # servo set angle to 0 and 90 degrees >>> r.arm = 0 >>> r.arm = 90 >>> # check state of capacitive touch >>> r.touch False
  3. Kid’s REPL Session >>> r.wheel =1 >>> r.wheel =0 >>>

    1+1 2 >>> 365*7 2555 >>> 365*41 14965 >>> r.arm =0 >>> r.arm =30 >>> r.arm =90 >>> r.arm =140 >>> r.wheel =-1 >>> r.wheel =0.5 >>> r.touch False >>> r.touch True (robo) pi@raspberrypi:~/tmp $ date Fri 17 May 09:20:01 BST 2019 (robo) pi@raspberrypi:~/tmp $ whoami pi (robo) pi@raspberrypi:~/tmp $ poweroff Connection to robopi closed by remote host. Connection to robopi closed.
  4. Setup • Install Raspbian on Raspberry Pi • Enable ssh

    and I2C in Raspbian • pip install adafruit-circuitpython-crickit tornado
  5. Remote Control 1. Forward 2. Backward 3. Stop 4. Right

    5. Left 6. Raise Hand 7. Lower Hand
  6. App Structure ├── conf.py ├── motors.py ├── server.py ├── static

    │ ├── main.css │ └── remote.jpg └── templates └── main.html
  7. main.html <!DOCTYPE HTML> <html lang="en"> <head> <title>Robot Remote</title> <link rel="stylesheet"

    href="{{ static_url('main.css') }}"> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width"> </head> <body> <h1>Robot Remote</h1> <div class="container"> <img src="{{ static_url('remote.jpg') }}" alt="ui"> <form method=post> <input type=submit name=action value=forward> <input type=submit name=action value=right> <input type=submit name=action value=left> <input type=submit name=action value=back> <input type=submit name=action value=stop> <input type=submit name=action value=raise> <input type=submit name=action value=lower> </form> </div> </body> </html>
  8. main.css h1 { margin: 0px; color: white; text-align:center; padding: 20px;

    width: 600px; background: linear-gradient(MediumTurquoise, BlueViolet); } .container { position: relative; } input { position: absolute; opacity: 0.0; } input[value="forward"] { left: 240px; top: 0px; width:150px; height:220px; }
  9. conf.py from os.path import dirname import os PORT = 8080

    APP_SETTINGS = dict( debug=bool(os.environ.get('APP_DEBUG')), static_path=(dirname(__file__) + '/static'), template_path=(dirname(__file__) + '/templates'), ) SERVO_MAX_ANGLE = 140 DC_SPEED = 1.0 TURN_DURATION = 0.2 DIRECTION = dict( forward=[1, 1], right=[1, 0], left=[0, 1], back=[-1, -1], stop=[0, 0], ) ANGLES = {} ANGLES['raise'] = SERVO_MAX_ANGLE ANGLES['lower'] = SERVO_MAX_ANGLE – 90
  10. server.py from tornado.web import RequestHandler, Application from tornado.ioloop import IOLoop

    from tornado.log import enable_pretty_logging from .conf import PORT, APP_SETTINGS from .motors import move, init_servo class MainHandler(RequestHandler): def get(self): self.render('main.html') def post(self): move(self.get_body_argument('action')) self.redirect('/') def main(): init_servo() enable_pretty_logging() app = Application([('/', MainHandler)], **APP_SETTINGS) app.listen(PORT) IOLoop.current().start() if __name__ == "__main__": main()
  11. motors.py from adafruit_crickit import crickit import time from .conf import

    SERVO_MAX_ANGLE, DC_SPEED, TURN_DURATION, DIRECTION, ANGLES def move_servo(action): crickit.servo_1.angle = ANGLES[action] def move_dc(action): direction = DIRECTION[action] crickit.dc_motor_1.throttle = direction[0] * DC_SPEED crickit.dc_motor_2.throttle = direction[1] * DC_SPEED if action in ['right', 'left']: time.sleep(TURN_DURATION) crickit.dc_motor_1.throttle = 0 crickit.dc_motor_2.throttle = 0 def move(action): if action in ['raise', 'lower']: move_servo(action) else: move_dc(action) def init_servo(): crickit.servo_1.actuation_range = SERVO_MAX_ANGLE
  12. conf.py from os.path import dirname, expanduser import os PORT =

    8080 APP_SETTINGS = dict( debug=bool(os.environ.get('APP_DEBUG')), static_path=expanduser('~/bookpusher_images'), template_path=(dirname(__file__) + '/templates'), ) BOOKS = list(range(1, 7)) DC = dict( speed=0.8, step_duration=0.38, forward=1, back=-1, ) SERVO_MAX_ANGLE = 140 HAND = dict( up=SERVO_MAX_ANGLE, down=SERVO_MAX_ANGLE - 90, delay=0.7, )
  13. server.py import random from tornado.web import RequestHandler, Application from tornado.ioloop

    import IOLoop from .conf import PORT, APP_SETTINGS, BOOKS from .push import init_servo, push_book, push_all class MainHandler(RequestHandler): def get(self): self.render('main.html', books=BOOKS) def post(self): book = self.get_body_argument('book') if book == 'all': push_all() else: book = random.choice(BOOKS) if book == 'random' else book push_book(int(book)) self.redirect('/') def main(): init_servo() app = Application([('/', MainHandler)], **APP_SETTINGS) app.listen(PORT) IOLoop.current().start()
  14. from adafruit_crickit import crickit import time, random from .conf import

    BOOKS, DC, SERVO_MAX_ANGLE, HAND def move_dc(direction, steps): crickit.dc_motor_1.throttle = direction * DC['speed'] crickit.dc_motor_2.throttle = direction * DC['speed'] time.sleep(DC['step_duration'] * steps) crickit.dc_motor_1.throttle = 0 crickit.dc_motor_2.throttle = 0 def swipe_hand(): crickit.servo_1.angle = HAND['down'] time.sleep(HAND['delay']) crickit.servo_1.angle = HAND['up'] time.sleep(HAND['delay']) def push_book(position): if position > 1: move_dc(DC['forward'], position - 1) swipe_hand() move_dc(DC['back'], position) def push_all(): books = list(BOOKS) random.shuffle(books) for book in books: push_book(book) def init_servo(): crickit.servo_1.actuation_range = SERVO_MAX_ANGLE push.py
  15. main.html <!DOCTYPE HTML> <html lang="en"> <head> <title>Robotic Librarian</title> <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width"> </head> <body> <h1>Robotic Librarian</h1> <form method=post> <button type=submit name=book value=random>Random</button> <button type=submit name=book value=all>All Books(Crazy Mode)</button><br/><br/> {% for book in books %} <button type=submit name=book value={{ book }}> <img src="{{ static_url('book%s.jpg' % book) }}" alt="book{{ book }}"> </button> {% end %} </form> </body> </html>