Skip to content
This repository has been archived by the owner on May 21, 2024. It is now read-only.

Commit

Permalink
Merge remote-tracking branch 'origin/dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
jpzg committed Sep 27, 2014
2 parents 18bb92f + 3adcb0f commit 57dd7ae
Show file tree
Hide file tree
Showing 8 changed files with 95 additions and 987 deletions.
713 changes: 0 additions & 713 deletions YunFirmata/YunFirmata.ino

This file was deleted.

2 changes: 1 addition & 1 deletion pyFirmata-AFMS
68 changes: 19 additions & 49 deletions python/linino.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from pyfirmata import Arduino, util
from tornado import websocket, web, ioloop
import json

### Values for pin types
INPUT = 0
Expand All @@ -10,64 +9,35 @@
SERVO = 4

### Values for motor direction
FORWARD = 0
BACKWARD = 1
BRAKE = 2
RELEASE = 3
FORWARD = 1
BACKWARD = 2
BRAKE = None # These don't work.
RELEASE = None

clients = []

yun = Arduino('/dev/ttyATH0', baudrate=115200)
s = yun.get_shield()
m = s.getMotor(1)
m.run(1)

cl = {'drive':None,'attachment':None} # Dict of roles, clients who fill them are put in under that index
ncl = [] # Array of clients without roles, e.g. any who are just looking at info.
def removeClient(client): # Remove client from ncl if present, before looking through roles
if client in ncl:
ncl.remove(client)
return 1
else:
for k,v in cl.iteritems():
if v == client:
cl[k] = None
return 2,k
return -1
m = s.get_motor(1)
m.dir(FORWARD)

def broadcast(data): # Broadcast a single message to clients. Pin updates, role openings, etc.
message = json.dumps(data);
for client in ncl:
client.write_message(message)
for client in cl.values():
if client:
client.write_message(message)
def retrieve(client,value):
client.send(value)

### Class to handle websocket connections
class SocketHandler(websocket.WebSocketHandler):

def open(self): # Add new client to dict of roles or array of role-less clients
if self not in ncl and self not in cl.values():
ncl.append(self)
print "[INFO] New connection:", self.request.remote_ip
def on_message(self, message): # Execute received message as python code and send back any returned value,
obj = json.loads(message)
if obj['type'] == 'event.switchRole': # Switch client role
result,role = removeClient(self)
if obj['data'] != 'null':
cl[obj['data']] = self
broadcast(json.dumps({'type':'event.closeRole', 'data':obj['data']}))
else:
ncl.append(self)
if result == 2:
broadcast(json.dumps({'type':'event.openRole','data':role}))
print '[EVT]', self.request.remote_ip + ' switched roles to ' + obj['data']
if obj['type'] == 'command':
print '[CMD]', obj, self.request.remote_ip
value = eval(message['data'])
if value != None:
print value
self.write_message(json.dumps({'type':'value','data':value}))
if self not in clients:
clients.append(self)
print "[INFO] New connection:", self.request.remote_ip

def on_message(self, message): # Execute received message using exec()
print '[CMD]', message, self.request.remote_ip
exec message

def on_close(self): # Remove client
removeClient(self)
clients.remove(self)
print "[INFO] Client disconnected:", self.request.remote_ip

app = web.Application([(r'/ws', SocketHandler)])
Expand Down
131 changes: 55 additions & 76 deletions www/index.html
Original file line number Diff line number Diff line change
@@ -1,86 +1,65 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta content="IE=11.0000"
http-equiv="X-UA-Compatible">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="Jacob Grossbard">
<link href="../../assets/ico/favicon.ico"
rel="shortcut icon">
<title>Robot Manager</title>
<!-- Bootstrap core CSS -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<!-- Custom styles for this template -->
<link href="index.css" rel="stylesheet">
<meta content="IE=11.0000"
http-equiv="X-UA-Compatible">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="Jacob Grossbard">
<link href="../../assets/ico/favicon.ico"
rel="shortcut icon">
<title>Robot Manager</title>
<!-- Bootstrap core CSS -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<!-- Custom styles for this template -->
<link href="index.css" rel="stylesheet">

<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->

<meta name="GENERATOR" content="MSHTML 11.00.9600.16521">
<meta name="GENERATOR" content="MSHTML 11.00.9600.16521">
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<button class="navbar-toggle" type="button"
data-toggle="collapse" data-target=".navbar-collapse"><span
class="sr-only">Toggle navigation</span> <span
class="icon-bar"></span><span class="icon-bar"></span><span
class="icon-bar"></span></button>
<a id="nav-title" class="navbar-brand" href="#"></a> </div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
<li><a href="#">Robot Manager</a></li>
<li><a href="config.html">Arduino Webpanel</a></li>
<li><a href="/cgi-bin/luci/;stok=d2a12883d15d3ff6fc652e6a836dab37">LuCI</a></li>
</ul>
<form
class="navbar-form navbar-right" onsubmit="handleSubmit(event)">
<input id="ip" class="form-control" type="text" placeholder="IP Address" value="">
</form>
</div>
</div>
</div>
<div class="container-fluid">
<div class="row">
<div class="col-sm-3 col-md-2 sidebar">
<ul class="nav nav-sidebar">
<li class="active"><a href="#">Control</a></li>
<li><a href="info.html">Reports</a></li>
<li>
<div id="conn-status" class="alert alert-warning">Not connected</div>
</li>
</ul>
</div>
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
<ul id="tabs" class="nav nav-tabs">
<li><a href="#drive" data-toggle="tab">Drive</a></li>
<li><a href="#attachment" data-toggle="tab">Attachment Control</a></li>
</ul>
<div class="tab-content">
<div id="drive" class="tab-pane">
<p>Hello world!</p>
</div>
<div id="attachment" class="tab-pane">
<div id="x-slider-c" class="touch-box">
<div id="x-slider" class="touch-slider"></div>
</div>
<div id="y-slider-c" class="touch-box-2">
<div id="y-slider" class="touch-slider-2"></div>
</div>
<div id="pos"></div>
<div id="pos2"></div>
</div>
</div>
</div>
</div>
</div>

<!-- Collapsible top navbar -->
<div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<button class="navbar-toggle" type="button"
data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span>
</button>
<a id="nav-title" class="navbar-brand" href="#"></a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
<li><a href="#">Robot Manager</a></li>
<li><a href="config.html">Arduino Webpanel</a></li>
<li><a href="/cgi-bin/luci/;stok=d2a12883d15d3ff6fc652e6a836dab37">LuCI</a></li>
</ul>
</div>
</div>
</div>
<!-- End of navbar -->

<div class="container-fluid">
<div id="conn-status" class="alert alert-warning">Not connected</div>
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
<div id="x-slider-c" class="touch-box">
<div id="x-slider" class="touch-slider"></div>
</div>
</div>
<div id="y-slider-c" class="touch-box-2">
<div id="y-slider" class="touch-slider-2"></div>
</div>
<div id="pos"></div>
<div id="pos2"></div>
</div>
</body>
<!-- Bootstrap core JavaScript
================================================== -->
Expand Down
82 changes: 20 additions & 62 deletions www/index.js
Original file line number Diff line number Diff line change
@@ -1,104 +1,63 @@
var socket; // WebSocket object
var host;
var role;
var drag_pos = 0;
var drag2_pos = 0;
var buffer = new Array(); // Buffer for functions to be called on message received

var arduino = function (ip, port) {
this.ip = ip;
this.port = port;
this.address = ip + ":" + port;
this.socket = WebSocket('ws://' + this.address + '/');
this.servoConfig = function(pin){
this.pin = pin;
this.socket.send("yun.servo_config(" + this.address + ")");
this.__defineGetter__("position",new function(position){
this.socket.send("yun.digital[" + pin + "].write(" + position + ")");
});
}
}

var get = function (msg, f, o) { // Execute any Yun method which returns a value
socket.send(msg); // o is caller object. Defaults to document
if (!o) { o = document; }
buffer.push(function (s) { f.call(o, s) });
}
var updatePins = function (info) {
var sel = $('#digital > tbody tr');
for (var i = 2; i < sel.length; i++) {
var sel2 = sel[i].select('td');
sel2[1] = info[i].mode;
sel2[2] = info[i].type;
sel2[3] = info[i].value;
}
}
var setServo = function () {
socket.send(JSON.stringify({ "type": 'command', "data": 'yun.digital[9].write(' + drag_pos + ')' }));
if (setServo.pos < 0) { setServo.pos = 0;}
if (setServo.pos != setServo.prev) {
socket.send('yun.digital[9].write(' + setServo.pos + ')');
setServo.prev = setServo.pos;
}
}
var setMotor = function () {
socket.send(JSON.stringify({ "type": 'command', "data": 'm.setSpeed(' + drag2_pos + ')' }));
if (setMotor.pos < 0) { setMotor.pos = 0;}
if (setMotor.pos != setMotor.prev) {
socket.send('m.speed(' + Math.round(setMotor.pos) + ')');
setMotor.prev = setMotor.pos;
}
}
setServo.pos = 0;
setMotor.pos = 0;

var servo_onMove = function (instance, event, pointer) {
$('#pos').text(instance.position.x * (160 / 255));
drag_pos = instance.position.x * (160 / 255);
setServo.pos = instance.position.x * (160 / 255);
}
var motor_onMove = function (instance, event, pointer) {
$('#pos2').text(instance.position.y);
drag2_pos = instance.position.y;
}
var disableTab = function(selection){
$(selection).attr('data-toggle','javascript:null(0)');
$(selection).parent().addClass('disabled');
}
var enableTab = function(selection){
$(selection).attr('data-toggle','tab');
$(selection).parent().removeClass('disabled');
setMotor.pos = instance.position.y;
}
var connect = function (ip) {
host = ip
$('#nav-title').text('Robot @ ' + host);
socket = new WebSocket('ws://' + host + ':3146/ws');
socket.onmessage = function (evt) {
obj = JSON.parse(evt.data.substr(5));
switch (obj.type) {
case 'event.closeRole':
disableLink('#tabs a[href="#' + obj.data + '"]');
break
case 'event.openRole':
enableLink('#tabs a[href+"#' + obj.data + '"]');
break
default:
buffer.pop().call(document, evt.data); // pops a function off the buffer and runs it with the received value as an arg
break
}
buffer.pop().call(document, evt.data); // pops a function off the buffer and runs it with the received value as an arg
}
socket.onerror = function (evt) {
$('#conn-status').removeClass('alert-success').addClass('alert-danger').text('Socket Error');
}
socket.onclose = function (evt) {
$('#conn-status').removeClass('alert-success').addClass('alert-warning').text('Socket Closed');
window.clearInterval(updatePins.timer);
window.clearInterval(setServo.interval);
window.clearInterval(setMotor.interval);
}
return socket
}
var handleSubmit = function (evt) {
evt.preventDefault();
connect($('#ip').value());
}

$(function () {
// Determine robot IP and open socket
//if (!window.location.host) { host = prompt('What is the robot IP?'); }
//else { host = window.location.host; }
host = '192.168.1.13';
connect(host);
host = '192.168.1.7';
var socket = connect(host);
socket.onopen = function (evt) {
$('#conn-status').removeClass('alert-warning').addClass('alert-success').text('Connected');
//socket.send('s = yun.get_shield()');
//socket.send('m = s.getMotor(1)');
//socket.send('m.run(1)');
//updatePins.timer = window.setInterval(updatePins, 1000);
setServo.interval = window.setInterval(setServo, 25);
setMotor.interval = window.setInterval(setMotor, 100);
}
Expand All @@ -115,4 +74,3 @@ $(function () {
servo.on('dragMove', servo_onMove);
motor.on('dragMove', motor_onMove);
});

21 changes: 0 additions & 21 deletions www/mobile-driver.css

This file was deleted.

Loading

0 comments on commit 57dd7ae

Please sign in to comment.