Skip to content

Instantly share code, notes, and snippets.

@jamesbulpin
Created March 13, 2019 17:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jamesbulpin/3e2e2d017ad272ea508abbfee6e79c24 to your computer and use it in GitHub Desktop.
Save jamesbulpin/3e2e2d017ad272ea508abbfee6e79c24 to your computer and use it in GitHub Desktop.
Simple Python HTTP server that provides an API to turn Fitbit watch orientation data into commands to a pan-tilt unit
import SocketServer
import SimpleHTTPServer
import math
import json
import pantilthat
pantilthat.pan(0)
pantilthat.tilt(0)
PORT = 9090
# From https://computergraphics.stackexchange.com/questions/8195/how-to-convert-euler-angles-to-quaternions-and-get-the-same-euler-angles-back-fr
def quaternion_to_euler(x, y, z, w):
t0 = +2.0 * (w * x + y * z)
t1 = +1.0 - 2.0 * (x * x + y * y)
roll = math.atan2(t0, t1)
t2 = +2.0 * (w * y - z * x)
t2 = +1.0 if t2 > +1.0 else t2
t2 = -1.0 if t2 < -1.0 else t2
pitch = math.asin(t2)
t3 = +2.0 * (w * z + x * y)
t4 = +1.0 - 2.0 * (y * y + z * z)
yaw = math.atan2(t3, t4)
return [yaw, pitch, roll]
class CustomHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
def do_POST(self):
content_length = int(self.headers['Content-Length'])
body = self.rfile.read(content_length)
#print (body)
x = json.loads(body)
if x.has_key("orientation"):
euler = quaternion_to_euler(
float(x["orientation"][1]),
float(x["orientation"][2]),
float(x["orientation"][3]),
float(x["orientation"][0]))
# Bring in to range 0-2*Pi to avoid a discontinuity in the middle
if euler[2] < 0:
euler[2] = euler[2] + math.pi * 2.0;
tilt = math.degrees(euler[2]) - 180
tilt = max(tilt, -30) # Limit to +/- 30 degrees
tilt = min(tilt, 30)
pantilthat.tilt(tilt)
pan = math.degrees(euler[1])
pan = max(pan, -30) # Limit to +/- 30 degrees
pan = min(pan, 30)
pantilthat.pan(pan)
print(pan,tilt)
self.send_response(200)
self.send_header('Content-type','text/txt')
self.end_headers()
self.wfile.write("OK")
httpd = SocketServer.ThreadingTCPServer(('', PORT),CustomHandler)
print "serving at port", PORT
httpd.serve_forever()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment