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
520
Executing scripts in a few milliseconds with MicroPython
marwano
1
480
Other Decks in Programming
See All in Programming
仕様駆動開発による爆速プロダクト開発 / Bakusoku Spec Driven Development
kobakei
0
130
『寄り添うラジオ』をAIで作る 体験価値から逆算した、会話しないUXと品質設計
theoriatec2024
3
180
UnityでSystem.Net.WebSocketsなWebSocketサーバが動かないのでUnity Monoのコードを覗いてみた / about implementing websocket server with unity mono
drumath2237
1
320
AWS DevOps Agentで インシデント対応をAIに任せたい
honmarkhunt
7
3.1k
Go × SIMDで高速化するベクトル検索 ~ルーフラインモデルでSIMDが効く境界を探れ! ~
po3rin
1
2.8k
更なる可用性を求めて、5年間運用したKotlinのアプリケーションをGoでリプレイスする話
ken_tunc
0
350
iOSDC2026登壇資料.pdf
riofujimon
0
180
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
510
Jetpack Compose メカニズム
skydoves
0
470
変化を抱擁するドキュメントの作り方 - ビジネスルール駆動開発がもたらす、コードとの新しい関係
ioki
2
220
iOSDC Japan 2026 - Swiftで作って学ぼう!データベース自作入門
kaseken
2
320
個人開発基盤をまるごとCloudflareに引っ越して爆速で総合的体験を向上させた話
tinykitten
0
200
Featured
See All Featured
Crafting Experiences
bethany
1
350
Designing for Timeless Needs
cassininazir
1
480
Faster Mobile Websites
deanohume
310
32k
From Legacy to Launchpad: Building Startup-Ready Communities
dugsong
0
340
The Impact of AI in SEO - AI Overviews June 2024 Edition
aleyda
6
1.2k
Kristin Tynski - Automating Marketing Tasks With AI
techseoconnect
PRO
0
520
Embracing the Ebb and Flow
colly
88
5.2k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
Docker and Python
trallard
47
4.2k
Designing Powerful Visuals for Engaging Learning
tmiket
1
580
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
360
31k
Building Adaptive Systems
keathley
44
3.2k
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/