Difference between revisions of "Ultrasound Triangulation"

From BITPlan Wiki
Jump to navigation Jump to search
(Pushed from BITPlan swa Wiki.)
 
 
(2 intermediate revisions by the same user not shown)
Line 3: Line 3:
  
 
<youtube>do2vzlPjbkM</youtube>
 
<youtube>do2vzlPjbkM</youtube>
 +
 +
= Experiment with BITPlan hardware =
 +
<HTML5video width="960" height="600" controls autoplay="false" loop="false">20190612_084825</HTML5video>
 +
[[File:angleplot2019-07-02.png|400px]] see {{Link|target=SG90-Servo}}
 +
== Source code ==
 +
<source lang='python'>
 +
# Test plotting distances at angle
 +
# WF 2019-06-13
 +
from pi.servo import Servo
 +
from pi.ultrasound import UltraSound
 +
import RPi.GPIO as GPIO
 +
import pantograph
 +
import math
 +
import time
 +
 +
# a point at the angle and distance given
 +
class DistPoint:
 +
  def __init__(self,angle,dist):
 +
    angle=angle-75
 +
    self.x=math.sin(math.radians(angle))*dist;
 +
    self.y=math.cos(math.radians(angle))*dist;
 +
#
 +
# plot the measured distances of the ultrasonic sensor
 +
#
 +
class DistancePlot(pantograph.PantographHandler):
 +
 +
  def setup(self):
 +
        print("Starting angle/distance measurement ...")
 +
        self.radius = min(self.width, self.height) / 2
 +
        self.maxdist=150
 +
 +
        self.us1=UltraSound(15,14)
 +
        self.us2=UltraSound(21,20)
 +
        self.us1.start()
 +
        self.us2.start()
 +
 +
        self.servo1 = Servo(23)
 +
        self.servo2 = Servo(24)
 +
        self.servo1.start()
 +
        self.servo2.start()
 +
        self.dpDict1={}
 +
        self.dpDict2={}
 +
        self.firstUpdate=True
 +
 +
  def ruler(self):
 +
        for dist in range(10,self.maxdist+10,10):
 +
          # draw the circle for the "rim" of the wheel
 +
          self.draw_circle(self.width/2, 0, self.scaleY(dist), "#f0f0f0")
 +
 +
  def scaleX(self,x):
 +
        return x*self.width/self.maxdist;
 +
 +
  def scaleY(self,y):
 +
        return y*self.height/self.maxdist;
 +
 +
  def valid(self,dist):
 +
      if dist>self.maxdist:
 +
        return False;
 +
      if dist<0:
 +
        return False;
 +
      return True;
 +
 +
  #
 +
  # plot the distance of the given dist/angle
 +
  #
 +
  def plotDistance(self,xofs,dangle,dpDict,dist,angle,step,color):
 +
    angle=angle+dangle
 +
    prevangle=angle-step
 +
    # only plot valid distances
 +
    if self.valid(dist):
 +
      # create the point
 +
      dp=DistPoint(angle,self.scaleY(dist))
 +
      if prevangle in dpDict:
 +
        dp2=dpDict.get(prevangle)
 +
        xofs=self.width/2+self.scaleX(xofs)
 +
        self.draw_line(self.width-(xofs+dp.x),dp.y,self.width-(xofs+dp2.x),dp2.y,color)
 +
      dpDict[angle]=dp
 +
 +
  def update(self):
 +
        if self.firstUpdate:
 +
          self.ruler()
 +
          self.firstUpdate=False
 +
        step=1
 +
        start=50
 +
        stop=110+step
 +
        meanCount=3
 +
        dx=0
 +
        dangle=7.5
 +
        for angle in range(start,stop,step):
 +
            pwm1=self.servo1.setAngle(angle)
 +
            pwm2=self.servo2.setAngle(angle)
 +
            dist1 = self.us1.meanDistance(meanCount)
 +
            time.sleep(0.02) # avoid indirect echos         
 +
            dist2 = self.us2.meanDistance(meanCount)
 +
            self.plotDistance(dx,dangle,self.dpDict1,dist1,angle,step,"#ff8000")
 +
            self.plotDistance(-dx,-dangle,self.dpDict2,dist2,angle,step,"#0000FF")
 +
            print angle,"{0:.2f}".format(pwm1),self.us1.distAsString(dist1),self.us2.distAsString(dist2)
 +
            # speed of servo is 0.1 secs per 60 degrees
 +
            time.sleep(0.1/6) #
 +
 +
if __name__ == '__main__':
 +
    try:
 +
      app = pantograph.SimplePantographApplication(DistancePlot)
 +
      app.run("0.0.0.0", 8000) 
 +
    except KeyboardInterrupt:
 +
        print("Aborted ultrasound distance measurement by User ... cleaning up GPIO")
 +
        GPIO.cleanup()
 +
 +
</source>
 
[[Category:Raspberry]]
 
[[Category:Raspberry]]

Latest revision as of 17:35, 21 October 2019

Experiment with BITPlan hardware

Angleplot2019-07-02.png see SG90-Servo

Source code

# Test plotting distances at angle 
# WF 2019-06-13
from pi.servo import Servo
from pi.ultrasound import UltraSound 
import RPi.GPIO as GPIO
import pantograph
import math
import time

# a point at the angle and distance given
class DistPoint:
  def __init__(self,angle,dist):
     angle=angle-75
     self.x=math.sin(math.radians(angle))*dist;
     self.y=math.cos(math.radians(angle))*dist;
#
# plot the measured distances of the ultrasonic sensor
#
class DistancePlot(pantograph.PantographHandler):

   def setup(self):
        print("Starting angle/distance measurement ...")
        self.radius = min(self.width, self.height) / 2
        self.maxdist=150

        self.us1=UltraSound(15,14)
        self.us2=UltraSound(21,20)
        self.us1.start()
        self.us2.start()

        self.servo1 = Servo(23)
        self.servo2 = Servo(24)
        self.servo1.start()
        self.servo2.start()
        self.dpDict1={}
        self.dpDict2={}
        self.firstUpdate=True

   def ruler(self):
        for dist in range(10,self.maxdist+10,10):
          # draw the circle for the "rim" of the wheel
          self.draw_circle(self.width/2, 0, self.scaleY(dist), "#f0f0f0")

   def scaleX(self,x):
        return x*self.width/self.maxdist;
 
   def scaleY(self,y):
        return y*self.height/self.maxdist;

   def valid(self,dist):
      if dist>self.maxdist:
        return False;
      if dist<0:
        return False;
      return True;

   #
   # plot the distance of the given dist/angle
   #
   def plotDistance(self,xofs,dangle,dpDict,dist,angle,step,color):
     angle=angle+dangle
     prevangle=angle-step	
     # only plot valid distances
     if self.valid(dist):
       # create the point
       dp=DistPoint(angle,self.scaleY(dist))
       if prevangle in dpDict:
         dp2=dpDict.get(prevangle)
         xofs=self.width/2+self.scaleX(xofs)
         self.draw_line(self.width-(xofs+dp.x),dp.y,self.width-(xofs+dp2.x),dp2.y,color)
       dpDict[angle]=dp

   def update(self):
        if self.firstUpdate:
           self.ruler()
           self.firstUpdate=False
        step=1
        start=50
        stop=110+step
        meanCount=3
        dx=0
        dangle=7.5
        for angle in range(start,stop,step):
            pwm1=self.servo1.setAngle(angle)
            pwm2=self.servo2.setAngle(angle)
            dist1 = self.us1.meanDistance(meanCount)
            time.sleep(0.02) # avoid indirect echos          
            dist2 = self.us2.meanDistance(meanCount)
            self.plotDistance(dx,dangle,self.dpDict1,dist1,angle,step,"#ff8000")
            self.plotDistance(-dx,-dangle,self.dpDict2,dist2,angle,step,"#0000FF")
            print angle,"{0:.2f}".format(pwm1),self.us1.distAsString(dist1),self.us2.distAsString(dist2)
            # speed of servo is 0.1 secs per 60 degrees 
            time.sleep(0.1/6) # 

if __name__ == '__main__':
    try:
      app = pantograph.SimplePantographApplication(DistancePlot)
      app.run("0.0.0.0", 8000)  
    except KeyboardInterrupt:
        print("Aborted ultrasound distance measurement by User ... cleaning up GPIO")
        GPIO.cleanup()