This is the python script:
#!/usr/bin/python
# -*- coding: Latin -1
import sys, cgi, cgitb, os, tempfile, time, picamera, colorsys, math
import pantilthat, UltraBorg
PH = pantilthat.pantilthat
PH.servo_enable(1, True)
PH.servo_enable(2, True)
PH.light_mode( 1 )
UBD = UltraBorg.UltraBorg()
UBD.Init() # Set the board up (checks the board is connected)
cgitb.enable(display=0, logdir="/var/log/cgi")
# import thunderborg python driver interface
import ThunderBorg
TB = ThunderBorg.ThunderBorg()
TB.i2cAddress = 0x29
# Setup the thunderborg
TB.Init() # Set the board up (checks the board is connected)
#set variables
var = 1
EXIT = 0
# setup application and read fieldstorage values to temp file and write a copy to cambot cgi-bin then read values into a form from the begining of the file.
def application(environ, start_response):
temp = tempfile.NamedTemporaryFile(suffix='_store', prefix='tmp_', dir='/var/www/cambot/cgi-bin/', delete='false')
temp.write(environ['wsgi.input'].read())
temp.seek(0)
form = cgi.FieldStorage(fp=temp, environ=environ, keep_blank_values=True)
# Ultrasonic Dist checks
# Read all four ultrasonic values
usm1 = UBD.GetDistance1()
usm2 = UBD.GetDistance2()
usm3 = UBD.GetDistance3()
usm4 = UBD.GetDistance4()
# Convert to the nearest millimeter
usm1 = int(usm1)
usm2 = int(usm2)
usm3 = int(usm3)
usm4 = int(usm4)
if usm1 != 0 and usm1 <300 :
status1 = "BLOCKED RL"
print status1
else:
status1 = "CLEAR"
print status1
if usm2 != 0 and usm2 <300 :
status2 = "BLOCKED RR"
print status2
else:
status2= "CLEAR"
print status2
if usm3 != 0 and usm3 <300 :
status3 = "BLOCKED FL"
print status3
else:
status3 = "CLEAR"
print status3
if usm4 != 0 and usm4 <300 :
status4 = "BLOCKED RL"
print status4
else:
status4 = "CLEAR"
print status4
# is direction clear?
if (status3 == "CLEAR" and status4 == "CLEAR") :
ahead = "CLEAR"
print "Ahead test = " + ahead
else:
ahead = "BLOCKED"
print "Ahead test = " + ahead
if (status1 == "CLEAR" and status2 == "CLEAR") :
behind = "CLEAR"
print "Behind test = " + behind
else:
behind = "BLOCKED"
print "Behind test = " + behind
#ahead = "CLEAR"
#behind = "CLEAR"
# Get speed settings, determine direction, and whether clear
sld1move = float(form.getfirst( "lspeedsv" ))
print sld1move
sld2move = float(form.getfirst( "rspeedsv" ))
print sld2move
# motors stopped
if (sld1move == 0 and sld2move == 0):
TB.MotorsOff()
# set speed left motor
TB.SetMotor2( float(sld1move) / 100.0)
# set speed right motor
TB.SetMotor1( float(sld2move) / 100.0)
# motors both + forward
if (sld1move > 0 and sld2move > 0 ) :
print "motor values greater than 0 ahead test = " + ahead
if ahead =="CLEAR" :
# set speed left motor
TB.SetMotor2( float(sld1move) / 100.0)
# set speed right motor
TB.SetMotor1( float(sld2move) / 100.0)
# Motors 1 + other 0 turn
if (sld1move > 0 and sld2move == 0 ) or (sld1move == 0 and sld2move > 0 ) :
print "motor values greater than 0 ahead test = " + ahead
if ahead =="CLEAR" :
# set speed left motor
TB.SetMotor2( float(sld1move) / 100.0)
# set speed right motor
TB.SetMotor1( float(sld2move) / 100.0)
# motors one - one + spin
if (sld1move > 0 and sld2move < 0 ) or (sld1move < 0 and sld2move > 0 ) :
print "motor values greater than 0 ahead test = " + ahead
if ahead =="CLEAR" :
# set speed left motor
TB.SetMotor2( float(sld1move) / 100.0)
# set speed right motor
TB.SetMotor1( float(sld2move) / 100.0)
# motors both - backward
if (sld1move < 0 and sld2move < 0 ) :
print "motor values less than 0 behind test = " + behind
if behind == "CLEAR" :
# set speed left motor
TB.SetMotor2( float(sld1move) / 100.0)
# set speed right motor
TB.SetMotor1( float(sld2move) / 100.0)
# set camera position
camerapos = form.getfirst( "cameraposv")
print camerapos
global pmove
global tmove
pmove = 0
tmove = 0
if camerapos == "A" :
tpos = 0
movet = 10
tpos = PH.get_tilt()
tmove = (tpos - movet)
if -89 <= tmove <= 89 :
PH.servo_two( tmove )
elif camerapos == "B" :
tpost = 0
movet = 10
tpost = PH.get_tilt()
tmove = (tpost + movet)
if -89 <= tmove <= 89 :
PH.servo_two( tmove )
elif camerapos == "C" :
ppos = 0
movep = 10
ppos = PH.get_pan()
pmove = (ppos - movep)
if -89 <= tmove <= 89 :
PH.servo_one( pmove )
elif camerapos == "D" :
ppos = 0
movep = 10
ppos = PH.get_pan()
pmove = (ppos + movep )
if -89 <= tmove <= 89 :
PH.servo_one( pmove )
# Led control
global ledv
ledv = form.getfirst("ledsv")
if ledv == "led-on":
PH.set_all(255,255,255)
PH.show()
print "LED On"
ledv = ""
elif ledv == "led-off":
PH.set_all(0,0,0)
PH.show()
print "LED Off"
ledv = ""
start_response( '200 OK', [('Content-Type', 'text/html')])
return [ "Recieved & Processed Left Speed = " + str( sld1move ) + "Right Speed = " + str( sld2move ) + "Blocked? front = " + ahead + " behind = " + behind + " Pan Pos. " + str( pmove ) + " Tilt Pos. " + str( tmove ) ]
This is the console log for one change showing the format of the fieldstorage string:
success lspeedsv=+0+&rspeedsv=+0+&ledsv=&cameraposv=D
cambot.php:464 create post is working!
cambot.php:475 Recieved & Processed Left Speed = 0.0Right Speed = 0.0Blocked? front = CLEAR behind = BLOCKED Pan Pos. 20 Tilt Pos. 0
The web server is setup to handle the php web page via fastcgi php7.0 fpm.socket whilst the cambot.py python script is run by uwsgi through a separate socket. The effect of the latter is that the python script is running from the start of njinx & uwsgi. I assume that pantilthat, thunderborg, and Ultraborg will be also be ready. The ultraborg is used to handle the four ultrasonic distance sensors as the driver gives a direct reading without messing with gpio pins.
Broadly this is working as expected although the sensor section works only when a change of speed is input but does not stop the cambot as it approaches an obstacle. I need to do some more research to find a way of looping the distance readings to fire’ motorsOff’ when an obstacle is detected in the line of travel.
I am sure this a far from optimal steup but is at the limit of my experience/knowledge!!