Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Creating Crazy Robotic Librarians
Search
Marwan Alsabbagh
May 26, 2019
Programming
200
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Creating Crazy Robotic Librarians
Marwan Alsabbagh
May 26, 2019
More Decks by Marwan Alsabbagh
See All by Marwan Alsabbagh
PyCon India 2018 - Executing scripts in a few milliseconds with MicroPython
marwano
2
200
Snow globe intruder alert system
marwano
0
530
Executing scripts in a few milliseconds with MicroPython
marwano
1
490
Other Decks in Programming
See All in Programming
sbt 2.0: takeoff
eed3si9n
0
150
Atomic Design, Enforced: Scaling Mobile Design Systems (next.app devCon / droidCon Berlin 2026)
steliosf
PRO
0
160
Findy - エンジニア向け会社紹介/Findy Company Deck
findyinc
6
400k
気持ちぃ〜角丸 Squircle
ryu1013
0
280
AI主導のプログラミング学習アプリを作ってみた
econanringo
0
160
半永久的に提供し続けられるプライベートクラウドを目指して ― 利用者の認知負荷を抑えるAPI抽象化とハードウェア世代交代の基盤設計
tomokon
0
480
最近”作らせてる” ローカルAIアプリの話
akit37
0
450
Are APIs Still Relevant in the AI Era?
soyuka
0
460
難しいけど、読めた。- OSSの入口に立った話。
sts11142
0
150
JAWS-UG 東京支部が始める、JAWS-UG支部コラボ / JAWS-UG lunchtime LT Collaboration
y0hgi
0
230
Embedded Swiftで作る自作USBデバイス によるiOSデバイスの自動テスト / iOSDC Japan 2026 glassfiber
glassfiber
0
330
KiroのSpecで「五目並べ」を作ってみる
satoshi256kbyte
1
370
Featured
See All Featured
End of SEO as We Know It (SMX Advanced Version)
ipullrank
3
4.4k
How to Grow Your eCommerce with AI & Automation
katarinadahlin
PRO
2
320
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.7k
[Rails World 2026] Durable orchestration on Rails: from continuation to workflow
palkan
1
730
エンジニアに許された特別な時間の終わり
watany
109
250k
Gemini Prompt Engineering: Practical Techniques for Tangible AI Outcomes
mfonobong
2
590
Building Experiences: Design Systems, User Experience, and Full Site Editing
marktimemedia
1
620
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
2
410
Darren the Foodie - Storyboard
khoart
PRO
4
4k
Speed Design
sergeychernyshev
33
2.2k
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
1
340
Statistics for Hackers
jakevdp
799
230k
Transcript
Creating Crazy Robotic Librarians Marwan AlSabbagh
1. Building 2. Teaching 3. Controlling Robots 4. Pushing Books
Outline
1. Building
Boards Adafruit CRICKIT HAT $35 Raspberry Pi 3 Model B+
$35 AA Battery Holder $3
Robot Chassis Kit Complete Kit $25 (separate DC motors $3
each)
Servo Standard servo - TowerPro SG-5010 $12.00
Exploded View
2. Teaching
Angles
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
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
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.
3. Controlling Robots
Setup • Install Raspbian on Raspberry Pi • Enable ssh
and I2C in Raspbian • pip install adafruit-circuitpython-crickit tornado
Remote Control 1. Forward 2. Backward 3. Stop 4. Right
5. Left 6. Raise Hand 7. Lower Hand
Button Overlay
App Structure ├── conf.py ├── motors.py ├── server.py ├── static
│ ├── main.css │ └── remote.jpg └── templates └── main.html
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>
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; }
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
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()
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
Robot Challenge
4. Pushing Books
Robotic Librarian 1. Push specific book 2. Push random book
3. Push all books
Wooden Frame
None
App Structure ├── conf.py ├── push.py ├── server.py └── templates
└── main.html
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, )
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()
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
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>
None
None
The End https://marwano.com/