RoRoRoomba - Ruby on Rails on Roomba Railsconf 2012

Preview:

DESCRIPTION

Charles Abbott's presentation slides about hacking Roombas using Ruby and a Rails app over serial cable, bluetooth, arduino, and a straight serial to wifi gateway (wifly). Given at RailsConf 2012, video available on Confreaks.com.

Citation preview

RoRoRoomba

Roomba on Ruby on Rails

Friday, April 27, 2012

Thanks!

• Nancy Dussault-Smith

• Joshua Lifton

• and iRobot for the Roombas!

Friday, April 27, 2012

Thanks!

Friday, April 27, 2012

Introductions

Friday, April 27, 2012

My Roomba

Friday, April 27, 2012

• Charles Abbott

• Life in Japan www.forthecode.org

• “The greatest obstacle...

konnichiwa

Friday, April 27, 2012

“The greatest obstacle to discovery

“Greatest obstacle...

Friday, April 27, 2012

“The greatest obstacle to discovery is not ignorance

“Greatest obstacle...

Friday, April 27, 2012

“The greatest obstacle to discovery is not ignorance, but

“Greatest obstacle...

Friday, April 27, 2012

“The greatest obstacle to discovery is not ignorance, but the illusion of knowledge” - Daniel J. Boorstin

“Greatest obstacle...

Friday, April 27, 2012

“Hack Me”

Friday, April 27, 2012

3 R’s

tokyorails.org

Friday, April 27, 2012

Ruby

Friday, April 27, 2012

Rails

Friday, April 27, 2012

Roomba

Friday, April 27, 2012

Roomba on Ruby on Rails

• SerialPort + Ruby controls Roomba

• Rails site that routes remote requests

• ???

• Profit!

Friday, April 27, 2012

Getting Started

Friday, April 27, 2012

Getting Supplies

Friday, April 27, 2012

and then...

Friday, April 27, 2012

my firstborn

Friday, April 27, 2012

Back on Track

Friday, April 27, 2012

Arduino LayoutRX = receiveTX = transmit

Friday, April 27, 2012

iRobot OI or SCI?

Friday, April 27, 2012

ROI? API?

Friday, April 27, 2012

Wired Up

Friday, April 27, 2012

Roomba + ArduinoWhat’s next?

Friday, April 27, 2012

Arduino Sandwich

Friday, April 27, 2012

Arduino Sketches

void setup(){}

void loop(){}

Friday, April 27, 2012

RAD?

Friday, April 27, 2012

Example Roomba Sketch

Friday, April 27, 2012

Debugging Arduino

Friday, April 27, 2012

Debugging Pains

[137] [255] [56] [1] [244]

Disconnect, Connect, Disconnect

Headless

Documentation woes

Friday, April 27, 2012

Past First Base

Friday, April 27, 2012

Arduino

Friday, April 27, 2012

Arduino Wireless XBEE

Friday, April 27, 2012

Bluetooth

Friday, April 27, 2012

USB to Serial

Friday, April 27, 2012

Wifi

Friday, April 27, 2012

Where to Start?

Friday, April 27, 2012

Simple Serial

Friday, April 27, 2012

Writing Code

def initialize(port, baud=115200)

@serial = SerialPort.new(port, baud, 8, 1, SerialPort::NONE)

sleep 0.2 api_setup_start sleep 0.1 api_setup_control

end

Friday, April 27, 2012

Writing Opcodes # Must call this first to start the serial command interface def api_setup_start write(128) end

# Enables user control of Roomba, puts SCI in safe mode def api_setup_control write(130) end

# Starts a normal cleaning cycle. def api_clean write(135) end

Friday, April 27, 2012

Modeling the ROI # api_drive(255, 0, 0, 0) //go backward # api_drive(0, 255, 0, 0) //go forward # api_drive(0, 0, 0, 0) // stop def api_drive(velocity_high, velocity_low, radius_high, radius_low) write(137, velocity_high, velocity_low, radius_high, radius_low) end

Friday, April 27, 2012

Complex Write and Read def api_querylist(*bytes) write(149, bytes.length, *bytes) wait_for_rx read end

Friday, April 27, 2012

The Bottom of the Barrel

def write(*args) args.each do |a| @serial.write a.chr end end

Friday, April 27, 2012

The Bottom of the Barrel

def read(timeout=50) @serial.read_timeout= timeout bytes = [] until (x = @serial.getbyte).nil? bytes.push(x) end bytes end

Friday, April 27, 2012

Pulling it Together

ls /dev/tty.*find your serial device

then jump into rails console

roo = Roomba.new(“/dev/tty.usbserial-xxx”)=> #<Roomba:0x00000103e5bec0 @serial=#<SerialPort:fd 9>>

Friday, April 27, 2012

“Hello Roomba” Demo

“Don’t Assume It--Prove It”- Tip, The Pragmatic Programmer

Friday, April 27, 2012

Forgetting to say “when”Pitfall #1

Friday, April 27, 2012

Status Reports

Friday, April 27, 2012

Flash Your Signdown the rabbit hole

Friday, April 27, 2012

Binary and Signed Integersdown the rabbit hole

Friday, April 27, 2012

Dealing With Binarydown the rabbit hole

def signed_integer(bytes) case bytes.size when 1 return (bytes[0] & ~(1 << 7)) - (bytes[0] & (1 << 7)) when 2 sixteenbit = bytes[0] << 8 | bytes[1] return (sixteenbit & ~(1 << 15)) - (sixteenbit & (1 << 15)) end end

learn more: http://en.wikipedia.org/wiki/Two%27s_complement#Calculating_two.27s_complement

Friday, April 27, 2012

A Hex Digressiondown the rabbit hole

Friday, April 27, 2012

Better Abstraction

Friday, April 27, 2012

Distance & Time

# distance is in mm # velocity is in mm/s (-500 to 500) def move(distance, degree=0, velocity=200)

distance = distance.to_i.abs #distance can never be negative

if distance == 0 #not moving, just spinning on axis # time = wheelbase * PI / 360degrees * degrees / velocity ABS time_in_seconds = calculate_spin_time(velocity, degree) else time_in_seconds = (distance.to_f / velocity.to_f).abs end

Friday, April 27, 2012

High Byte, Low Byte # distance is in mm # velocity is in mm/s (-500 to 500) def move(distance, degree=0, velocity=200) distance = distance.to_i.abs #distance can never be negative if distance == 0 #not moving, just spinning on axis # time = wheelbase * PI / 360degrees * degrees / velocity ABS # wheelbase might be different for different roombas time_in_seconds = calculate_spin_time(velocity, degree) # now that we know how long to spin, set degree to 1 so it will spin roomba instead of put it on an arc degree = 1 else time_in_seconds = (distance.to_f / velocity.to_f).abs end

set_velocity(velocity) set_degree(degree)

Friday, April 27, 2012

Move!

api_drive(@velocity_high, @velocity_low, @radius_high, @radius_low)

start_moving = Time.now

until (start_moving - Time.now).abs >= time_in_seconds sensors = get_readings(:bumps_and_drops, :wall) break if sensors[:bumps_and_drops][:formatted].to_i(2) > 0 end

api_drive(0,0,0,0) sensors

Friday, April 27, 2012

‘Move’ Demo

Friday, April 27, 2012

L...a...te..n....c..yPitfall #2

...

no!

no!

yes!

no!...Friday, April 27, 2012

Cut out the Middle Men

*Arduino is still awesome, and I encourage you to try it.

Friday, April 27, 2012

What Freedom Looks Like

Friday, April 27, 2012

Logic Level Converter

http://www.sparkfun.comhttp://www.sparkfun.com

Friday, April 27, 2012

Prototyping!

Friday, April 27, 2012

SerialPort || TCPSocket

All we need is an IP address and a Port!

Friday, April 27, 2012

Connected and then...

............................never ending silence..........

Friday, April 27, 2012

UART

UniversalAsynchronousReceiver (RX)

Transmitter (TX)

Friday, April 27, 2012

UART an Angel

Friday, April 27, 2012

All you get is #$@#!Pitfall #3

.4....U.

......V.

.-....L.

.7....T.

./....S.

.0....O.

.4....V.

.-....S.

.0....Y.

.*....V.

.-....U.

......R.

.1....W.

.,....R.

.1....V.

.-....S.

.0....N.

.5....[.

.(....M.

.6....R.

.1....Q.

.2....V.

.-....P.

.3....Y.

.*....S.

.0....U.

......L.

.7....T.

./....R.

.1......

......+.

.`....N.

.=......

........

......H.

.B......

........

........

......e.

.!......

........

.l....,.

.W....V.

.-....R.

.1....M.

.6....B.

.A....V.

.-....V.

.-....N.

.5....H.

.;....T.

./....L.

.7....M.

.6....H.

.;....K.

.8....S.

.0....U.

......O.

.4....U.

......Q.

.2....P.

.3....R.

.1....W.

.,....U.

......I.

.:....T.

./....L.

.7....M.

.6....Q.

.2....L.

.7....U.

......P.

.3....O.

.4....W.

.,....L.

.7....U.

......V.

.-....Z.

.)....Q.

.2....V.

.-....^.

.%....Q.

.2....O.

.4....M.

.6....Q.

.2....T.

./....M.

.6....X.

.+....N.

.5....N.

.5....U.

......R.

.1....`.

.#....Q.

.2....U.

......R.

.1....J.

.9....P.

.3....O.

.4....[.

.(....R.

.1....X.

.+....Y.

.*....S.

.0....T.

./....Y.

.*....Y.

.*....\.

.'....T.

./....W.

.,....U.

......Q.

.2....L.

.7....T.

./....[.

.(....V.

.-....N.

.5....Q.

.2....U.

......N.

.5....V.

.-....Q.

.2....T.

./....O.

.4....U.

......Q.

.2....O.

.4....W.

.,....N.

.5....W.

.,....S.

.0....X.

.+....S.

.0....Q.

.2....T.

./....L.

.7....T.

./....V.

.-....N.

.5....S.

.0....O.

.4....N.

.5....N.

.5....P.

.3....O.

Friday, April 27, 2012

All you get is #$@#!Pitfall #3

Solution #1: RTFM

Friday, April 27, 2012

All you get is #$@#!Pitfall #3

Solution #2: Factory Defaults

Friday, April 27, 2012

All you get is #$@#!Pitfall #3

Solution #3: RTFM, again...

Friday, April 27, 2012

All you get is #$@#!Pitfall #3

Solution #3: RTFM, again...

Friday, April 27, 2012

Wifly ConfigurationP195:~ charles$ telnet 169.254.1.1 2000Trying 169.254.1.1...Connected to 169.254.1.1.Escape character is '^]'.*HELLO*$$$CMDset comm close 0AOK<2.23>set comm open 0<2.23>set sys printlvl 0<2.23> saveStoring in config<2.23> reboot

Friday, April 27, 2012

Pretty Prototype...

Friday, April 27, 2012

Roomba Wifi

Friday, April 27, 2012

Roomba Wifi

Friday, April 27, 2012

3 Final Hurdles

nope nope huh?

Friday, April 27, 2012

Wifly Option (a)Hurdle 1

Friday, April 27, 2012

“Hold, hold,...Hurdle 1

Friday, April 27, 2012

Wifly Option (b)Hurdle 1

Friday, April 27, 2012

The Stateless Web Tax

def initialize(port, baud=115200) sleep 0.2 api_setup_start sleep 0.1 api_setup_control

Hurdle 2

Friday, April 27, 2012

Device Busy

OK Errno::EBUSY: Resource busy

CONCURRENTREQUESTS

Hurdle 3

Friday, April 27, 2012

Socket Server

Roomba Socket Serverstartserver = TCPServer.open(port) # Socket to listen onroomba = Roomba.new(location)

Thread.abort_on_exception = trueloop do puts "Roomba Socket Server Running! (15 second timeout)" Thread.start(server.accept) do |client|

# => Read the incoming TCP Socket request # => Pass the command to the roomba client.close # Disconnect from the client endend

Pseudocode

Hurdle 2 & 3

Friday, April 27, 2012

Extended Demo

“Coding Ain’t Done ‘Til All The Tests Run”- Tip 63, The Pragmatic Programmer

Friday, April 27, 2012

Looking Forward

Friday, April 27, 2012

Testing Drones

• How do you run software tests on something in the physical world?

Friday, April 27, 2012

Roomba Simulator

Friday, April 27, 2012

Test the Simulation

Friday, April 27, 2012

Compare with Live Test

Bring it!

Friday, April 27, 2012

Simulator Scenarios

Friday, April 27, 2012

Challenges

If i tape a marker on Roomba...Map out a room...

Friday, April 27, 2012

Physical Computing?

Jeremiah Palecek http://nerdkore.com

Why you should care.

Friday, April 27, 2012

By 2020

Ericsson White Paper 284 23-3149 Uen | February 2011

Friday, April 27, 2012

Already

http://techcrunch.com/2012/02/14/the-number-of-mobile-devices-will-exceed-worlds-population-by-2012-other-shocking-figures/

“By 2016, there will be 1.4 mobile devices per capita. That year, there will be over 10 billion mobile-connected devices, including machine-to-machine (M2M) modules.”

Friday, April 27, 2012

People then Things

Ericsson White Paper 284 23-3149 Uen | February 2011

Friday, April 27, 2012

People and Things

https://trandi.wordpress.com/2011/09/26/vfd-clock-connects-to-the-internet/

Friday, April 27, 2012

People and Things

http://lifeboat.co.nz/the-finished-wireless-water-sensor/Friday, April 27, 2012

Just Getting Started

Friday, April 27, 2012

“A Pragmatic Philosophy”

Invest Regularly in Your Knowledge Portfolio

- Tip 8, The Pragmatic Programmer

“Simon Stevin!”

Friday, April 27, 2012

An Eccentric

Friday, April 27, 2012

Who is Simon Stevin?•waterway, spillways, sluices•navigation, steering•interest rate tables•The Art of Fortification •Copernican system

•treatise on perspective•musical tuning•civil unrest handbook•Trigonometry

•hydrostatic paradox•optics, geography, philosophy•and more...

Friday, April 27, 2012

1585, De Thiende

“The Tenths”35pg

Friday, April 27, 2012

Changes the World

“What seems a wonder, is not really a wonder.” - Simon Stevin

Friday, April 27, 2012

Fork it!

github.com/tokyorails

Charles Abbottwww.forthecode.org

Friday, April 27, 2012

RoRoRoomba

Friday, April 27, 2012