Shop OBEX P1 Docs P2 Docs Learn Events
P2BrightBall: P2+BW Camera as a Position Sensor, Balancing a White Marble — Parallax Forums

P2BrightBall: P2+BW Camera as a Position Sensor, Balancing a White Marble

This is some fun experiment and work in progress. Goal is to control the path of the marble.

Hardware consists of a P2 Kiss Bord with attached BW Camera as 2-dimensional position sensor to detect a white marble on a black background. The marble runs on a plain, which can be tilted in two directions using 2 standard 180° RC servos. Mechanics is a labyrinth game.
Diameter of this glass marble is 13,77mm, weight: 3.35 grams
The usable size of the plain is 264mmx223mm
Vertical distance of the camera from plain: 390mm
Camera: https://forums.parallax.com/discussion/178031/connecting-a-bw-320x320-pixels-camera-arducam-hm01b0-to-parallax-propeller-p2-via-4-lines#latest but using resolution 160x160 Pixels
There is a 1W LED lamp close to the camera to avoid asymmetrical shadows.

There are some camera projects in the net to be found mostly using some sort of AI with complicated and slow picture analysis. In this case here we can "design the problem", so we are using a very dark background and a very bright marble. Also we know for example the size of the marble. The automatic exposure of this camera works well, so we can use an absolute threshold.
The idea is then to have a simple way of finding the marble in the picture to get a high update rate for the position. For sake of speed also the resolution of the picture is reduced.

This is, how the camera sees the marble in the top left corner:

The wooden frame is rather bright too, so this is cut away.

The very simple method to get the position is right now to consider every pixel with brightness > 210 as part of the marble.

pub calcBallPos() | index, line , val, n, nc, nl '###########################################
    n, nc, nl:=0 , 0 , 0

    repeat line from LMIN to LMAX
        repeat index from CMIN to CMAX
            val:= picBuf.byte[line*(164) + index+4] ' 4 border pixels
            if(val>BBRIGHT)
               'term.tx(grey95.byte[95 - 95*val/255])
               n+=1
               nc+=index 
               nl+=line
    if(n>0)  
      colPos:= 10*nc/n
      linePos:= 10*nl/n

The idea is to try a PID-controller or rather two of them for the 2 directions. At the moment I am trying to learn about the system. There is an interesting Autotune Method to set the PID parameters, which gets information about the system via a Relay test: https://pages.mtu.edu/~tbco/cm416/Atune.html
So with an angle amplitude of 9 degrees at the servo (at the plain it is less), we get the following behaviour:

Cycle time for this is about 4600ms and resulting amplitude is about 89 rows.

....
Cheers Christof

Comments

Sign In or Register to comment.