Last active
August 29, 2015 14:11
-
-
Save GabiThume/12514b45b9a8783e360e to your computer and use it in GitHub Desktop.
MozFest code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
noflo = require 'noflo' | |
Mirobot = null | |
sleep = (ms) -> | |
start = new Date().getTime() | |
continue while new Date().getTime() - start < ms | |
class ControlMirobot extends noflo.Component | |
description: 'Control Mirobot.' | |
icon: 'pencil' | |
constructor: -> | |
@Mirobot = null | |
@url = null | |
@mirobot = null | |
@commands = [] | |
@points = [] | |
@inPorts = | |
url: new noflo.Port 'string' | |
start: new noflo.Port 'bang' | |
stop: new noflo.Port 'bang' | |
commands: new noflo.ArrayPort 'object' | |
points: new noflo.Port 'object' | |
lib: new noflo.Port 'object' | |
@outPorts = | |
path: new noflo.Port 'object' | |
@inPorts.lib.on 'data', (@Mirobot) => | |
@inPorts.url.on 'data', (data) => | |
@commands = [] | |
@url = data | |
if not @mirobot? | |
console.log 'Connecting on', @url | |
@mirobot = new @Mirobot @url | |
@inPorts.start.on 'data', (data) => | |
if @mirobot? | |
@parseThing @commands, 0 | |
@inPorts.stop.on 'data', (data) => | |
@commands = [] | |
if @mirobot? | |
@mirobot.stop() | |
@inPorts.commands.on 'data', (cmd, i) => | |
@commands[i] = cmd | |
@inPorts.points.on 'data', (data) => | |
@points = data.items | |
parseThing: (thing, currentPoint) -> | |
if thing? and thing.cmd? and @[thing.cmd]? | |
@[thing.cmd](thing, currentPoint) | |
else if thing instanceof Array | |
for item, i in thing | |
continue unless item? | |
@parseThing item, i | |
drawCommand: (position) => | |
return unless @inPorts.points.isAttached() | |
return unless @outPorts.path.isAttached() | |
if position < @points.length-1 | |
path = [] | |
path.push @points[position] | |
path.push @points[position+1] | |
@outPorts.path.send path | |
forward: (distance, currentPoint) => | |
@setIcon 'arrow-up' | |
@mirobot.move('forward', distance.arg, (state, msg, recursion) => | |
# if state != 'started' | |
# sleep 50 | |
# else | |
# @drawCommand currentPoint | |
) | |
back: (distance, currentPoint) => | |
@setIcon 'arrow-down' | |
@mirobot.move('back', distance.arg, (state, msg, recursion) => | |
# if state != 'started' | |
# sleep 50 | |
# else | |
# @drawCommand currentPoint | |
) | |
left: (angle, currentPoint) => | |
@setIcon 'mail-reply' | |
@mirobot.turn('left', angle.arg, (state, msg, recursion) => | |
# if state != 'started' | |
# sleep 50 | |
# else | |
# @drawCommand currentPoint | |
) | |
right: (angle, currentPoint) => | |
@setIcon 'mail-forward' | |
@mirobot.turn('right', angle.arg, (state, msg, recursion) => | |
# if state != 'started' | |
# sleep 50 | |
# else | |
# @drawCommand currentPoint | |
) | |
pause: -> | |
@mirobot.pause() | |
resume: -> | |
@mirobot.resume() | |
ping: -> | |
@mirobot.ping() | |
penup: -> | |
@mirobot.penup() | |
pendown: -> | |
@mirobot.pendown() | |
exports.getComponent = -> new ControlMirobot |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
noflo = require 'noflo' | |
# Converts from radians to degrees. | |
Math.degrees = (radians) -> | |
return radians * 180 / Math.PI | |
class PointsToPolar extends noflo.Component | |
description: 'Converts cartesian coordinates to polar coordinates.' | |
icon: 'paint-brush' | |
constructor: -> | |
@mirobotAngle = 0 | |
@commands = [] | |
@inPorts = | |
points: new noflo.Port 'object' | |
@outPorts = | |
polar: new noflo.Port 'object' | |
@inPorts.points.on 'data', (data) => | |
return unless @outPorts.polar.isAttached() | |
@mirobotAngle = 0 | |
if data.items? | |
points = data.items | |
else | |
points = data | |
@parsePoints points | |
@outPorts.polar.send @commands | |
parsePoints: (start, end) => | |
if start? and end? and start.x? and end.x? | |
@pathFinding(start, end) | |
else if start instanceof Array | |
for item, i in start | |
continue unless item? | |
if start[i+1]? | |
@parsePoints item, start[i+1] | |
pathFinding: (from, to) => | |
# Distance is a simple Pythagoras | |
dx = to.x - from.x | |
dy = to.y - from.y | |
distance = Math.sqrt(dx*dx + dy*dy) | |
# Calculate the angle | |
arctangent = Math.atan2(dx, dy) | |
angle = Math.degrees(arctangent) | |
# Calculating the walking angle based on previous mirobot angle | |
@walkingAngle = angle - @mirobotAngle | |
if @walkingAngle < 0 | |
@walkingAngle = @walkingAngle + 360 | |
@mirobotAngle = angle | |
if @mirobotAngle >= 360 | |
@mirobotAngle = @mirobotAngle - 360 | |
commandDirection = | |
cmd: null | |
arg: null | |
if @walkingAngle <= 180 | |
commandDirection.cmd = 'right' | |
commandDirection.arg = @walkingAngle.toString() | |
else | |
commandDirection.cmd = 'left' | |
commandDirection.arg = (360 - @walkingAngle).toString() | |
commandForward = | |
cmd: 'forward' | |
arg: distance.toString() | |
@commands.push commandDirection | |
@commands.push commandForward | |
exports.getComponent = -> new PointsToPolar |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
noflo = require 'noflo' | |
class TSP extends noflo.Component | |
description: 'Ordenates points based on the minimum distance between them.' | |
icon: 'code-fork' | |
constructor: -> | |
@points = [] | |
@inPorts = | |
points: new noflo.Port 'object' | |
@outPorts = | |
points: new noflo.Port 'object' | |
@inPorts.points.on 'data', (data) => | |
return unless @outPorts.points.isAttached() | |
return unless data.items.length != 0 | |
@points = data.items | |
@tspGreedy() | |
@outPorts.points.send @points | |
distance: (from, to) => | |
dx = @points[to].x - @points[from].x | |
dy = @points[to].y - @points[from].y | |
return Math.sqrt(dx*dx + dy*dy) | |
# Inspired by https://code.google.com/p/google-maps-tsp-solver/ | |
tspGreedy: => | |
current = 0 | |
currentDistance = 0 | |
lastNode = 0 | |
visited = (false for i in [0...@points.length]) | |
bestPath = (0 for i in [0...@points.length]) | |
for step in [0...@points.length-1] | |
visited[current] = true | |
bestPath[step] = current | |
nearest = 999999 | |
near = -1 | |
for next in [1...@points.length] | |
if !visited[next] && ((@distance current, next) < nearest) | |
nearest = @distance current, next | |
near = next | |
currentDistance += @distance current, near | |
current = near | |
bestPath[@points.length-1] = current | |
@points = (@points[i] for i in bestPath) | |
exports.getComponent = -> new TSP |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment