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
更なる可用性を求めて、5年間運用したKotlinのアプリケーションをGoでリプレイスする話
ken_tunc
0
360
Kiroで創り、AgentCoreで繋ぐ!AWSで実践する「AI-DLC」から「AIエージェント統合」までの最新地図
licux
4
780
MVNOの申込からeSIM開通までをiOSアプリでつなぐ- 本人確認・MNP・通信事業者基盤をまたぐ実装
satotakeshi
0
470
WebMCP Challenge に星空観察アプリで参加した話
okajun35
0
190
thread_parallel_with_free-threaded_Python_and_NumPy.pdf
riku_sakamoto
0
360
マイコン向けの軽量Ruby「PicoRuby」で各種デバイスを制御するネイティブアプリの実現手法
bash0c7
0
440
変化を抱擁するドキュメントの作り方 - ビジネスルール駆動開発がもたらす、コードとの新しい関係
ioki
2
220
すこし踏み込む CancellationToken
htkym
2
960
20260914 AIエージェント時代のPlatform Engineering LLM基盤とプロダクトの責務境界線
kanfab1
7
2.2k
Verilogで学ぶCPU自作入門.pdf
uyuki234
6
2.7k
標準パッケージに uuid が追加された 背景から見る Go らしい意思決定 / go_127_uuid_decision
convto
5
8.3k
個人開発基盤をまるごとCloudflareに引っ越して爆速で総合的体験を向上させた話
tinykitten
0
200
Featured
See All Featured
The Power of CSS Pseudo Elements
geoffreycrofte
82
6.6k
What the history of the web can teach us about the future of AI
inesmontani
PRO
1
710
Paper Plane (Part 1)
katiecoart
PRO
2
11k
The Art of Programming - Codeland 2020
erikaheidi
57
14k
AI Search: Where Are We & What Can We Do About It?
aleyda
0
8k
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
1
390
HU Berlin: Industrial-Strength Natural Language Processing with spaCy and Prodigy
inesmontani
PRO
0
710
Agile Actions for Facilitating Distributed Teams - ADO2019
mkilby
0
280
How to Get Subject Matter Experts Bought In and Actively Contributing to SEO & PR Initiatives.
livdayseo
0
200
A brief & incomplete history of UX Design for the World Wide Web: 1989–2019
jct
2
510
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
310
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
56
3.5k
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/