Introduction: Low Cost Accurate 3D Positioning
The 3D positioning and gesture tracking technology incorporated in all of today's sensors, such as theKinect Sensor or Leap Motion Controller, as well as the camera/sensor included in the VR bundles of Oculus Rift or HTC Vive, is based on IR.
The challenge that this project addresses is to develop a sensor device, alternative to the 3D IR camera/sensor, which -
- costs merely 6.4%, ($7.6, i.e, counterfeit Arduino Uno + geared motor) compared to 2 x Oculus Sensor (2 x $59 as stated inhttps://www.oculus.com/accessories/), and also much less than other IR cameras/sensors.
- has completely open source hardware (an Arduino project), software and tracking algorithms, as opposed to the hardware and tracking algorithms of those IR cameras/sensors.
- is precise up to 1 mm, along all 3 dimensions, as opposed to a resolution of around 1 cm provided by today's IR camera/sensors.
- can be reconstructed from scratch in a mere 10 minutes, and has very simple schematics and build design.as opposed to IR cameras/sensors
- is able to see beyond opaque obstruction, and whose tracking precision is not compromised owing to white or shiny surfaces.
Brief Explanation of Tracking Algorithm
- Water potentiometer gives the voltage at tip of the stylus.
- Voltage gives a plane containing the tip of the stylus
- Geared DC motor rotates the sensor to give 3 different voltages for the same fixed tip.
- 3 different voltages implies 3 non-parallel plane equations.
- 3 non-parallel planes intersect at a unique point.
- x,y,z coordinates of that point is the stylus tip's location.
Detailed Explanation of Tracking Algorithm
The basic idea behind this sensor is the use of a parallelopiped water container as a water potentiometer device. Since water is an electrolyte, its composition, hence, conductivity does not remain uniform on passing current through it. Thus, to retain uniform composition, electrolysis must be minimized. In order to minimize electrolysis, the following adaptations have been made -
- The microcontroller C++ code constantly keeps swapping over the polarity of voltage drop across the water, to cancel out the disturbance in its composition.
- The microcontroller C++ code has been optimized for minimum cycle time period, (so, it may seem unnecessarily lengthy) to maximize the frequency of swapping of the voltage drop polarity.
Owing to the above adaptations, the water always has uniform composition and hence, uniform conductivity at all points inside water. Thus, the voltage drops linearly with respect to the displacement from one electrode.
A parallel pair of aluminium sheet electrodes are attached to the water container at two opposite faces, and inclined at an angle 'alpha' ( = 75 degrees or (5/12)*PI radians) to the horizontal base of the parallelopiped container. These two apply a voltage drop of 5 volt across the water. A metal pin, connected to Arduino Uno's ADC input, is attached to the tip of the stylus. This pin tracks the voltage at the tip of the stylus, i.e., output voltage of the water potentiometer, when dipped into the water.
NOTE - The current travels along a slant direction (indicated by 'J' vector i.e. current density vector), rather than in horizontal direction. This is because, since the 2 electrode planes at the opposite ends are equi-potential surfaces, the electric field vector and current density vector are normal to those 2 end planes. So, the current originates and travels along that slant direction.
By knowing the output voltage, the plane equation (with respect to lab reference frame) can be derived, which is the locus of all points, inside water, which are at the same voltage as the tip of the stylus. The sensor is constantly rotating anticlockwise in the horizontal plane, with a small uniform angular velocity. The axis of rotation is parallel to the z-axis and passes through the intersection of diagonals of the horizontal base of the parallelopiped container.
NOTE - The sensor is rotated by a geared DC motor rather than a servo, since, it would cause frequent jerks, which would fluctuate the voltage at a fixed point (fixed with respect to sensor reference frame) in water.
The sensor reads the output voltage of the water potentiometer at 3 different angular positions. Thus, 3 different output voltages are read for the same fixed stylus tip (fixed with respect to lab reference frame). A plane equation (with respect to lab reference frame) is derived for each of these 3 output voltages. These3 planes are non-parallel due to the rotation of the sensor. Moreover, this system of 3 non-homogeneous equations is consistent, and has one unique solution, since it it can be proved that matrix 'A' (refer next derivation), is non-singular, i.e., its determinant is non-zero.
NOTE - A parallelopiped water container must be be used instead of a cubical or cuboidal container, since, in case of a cubical or cuboidal container, the intersection of the 3 non-parallel planes would be a lineinstead of one unique point.
In simple terms, the 3 non-parallel planes intersect at one unique point. Solving this system of equations (3 equations for 3 unknown variables), using matrix equations, the x, y and z coordinates (with respect to lab reference frame) of the intersection point is obtained. This is the precise position vector of the stylus tip.
Serial output from Arduino Uno
Arduino Uno, then, prints these x, y and z coordinates to the Android app, serially, via USB OTG. The Android smartphone is attached to the rotating sensor, along with Arduino Uno. The Android app then relays these x,y,z coordinates to the client app running on the Laptop, via Wi-Fi. The format of serial output from Arduino Uno is as follows -
DATATYPE: x, y, z are all in float.
-128.00 <= x <= +127.00 ,
-128.00 <= y <= +127.00 ,
0.00 <= z <= +255.00 ,
When the tip of the stylus is removed from water, only then, x=y=z= 257.00
258 is the code for "start of coordinates".
- Sculpting and Painting in Virtual Reality ( interfaced with a VR headset such the Google Cardboard, Oculus Rift , or HTC Vive).
- Interacting with holograms viewed from devices such as Microsoft Hololens.
- CGI designing.
- Virtually building models to be 3D printed.
A World Changing Idea and How it Benefits the Society
- This sensor can be quickly and easily be constructed even by non-engineers and high school students.So it can be used for a more interactive and fun way of learning science by interacting with holograms.
- This sensor is a low cost alternative to IR cameras/sensors for amateur or professional artists.
- Since its tracking algorithms and hardware is completely open source, it can be developed by researchers around the world to further minimize its cost and achieve a greater deal of precision.
- Imagine one of this low cost DIY sensor at every home on the planet. It is surely going to revolutionize the way we think and begin a new era of computing since it enables 3D interaction with computers.
Remarks and Drawbacks
- The 1mm resolution is just a constraint imposed by Arduino Uno's 10-bit resolution ADC. I'm still in high school, so I know to develop only on Arduino Uno. Maybe a more powerful microcontroller would provide greater ADC resolution and hence, more precise positioning.
- Sudden movement of the stylus cause ripples or disturbance in water which can hamper tacking precision of the coordinates of the stylus tip because water takes some time to re-stabilize.Thus, the thinnest possible stylus must be used to minimize the ripples or disturbance in water.
- This can be scaled up into a larger sensor, but with a larger sensor, portability issues come in due to the weight of water. I mean with a larger sensor you'll have to empty the water, shift it to its new place, and the fill it again with water. But no issues if you've decided on keeping it in one place.
- Fritzing circuit schematics - The source code of Fritzing is licensed under GNU GPL v3, the documentation and part designs under Creative Commons Attribution-ShareALike 3.0 Unported. http://fritzing.org/home/
- MatrixMath C++ library - licensed under GPL2. Github repository - https://github.com/codebndr/MatrixMath
Step 1: Gather All Components
- Arduino Uno R3 ( counterfeit Arduino Uno board costing $6.2 )
- geared DC motor ( 20 RPM or less )
- aluminium foil ( kitchen aluminium foil )
- 3D printed parallelopiped water container ( The water container must be a parallelopiped , open at the top, base angles equal to 75 degrees and it dimensions 20cm x 10cm x 8cm )
- 5V AC-DC power adapter ( current rating= 2 A)
Step 2: Upload C++ Code to Arduino Uno
Download the Arduino IDE from https://www.arduino.cc
.Download 3d_sensor_c_code_rev12.ino and MatrixMaster zip archive from the Files section. Open 3d_sensor_c_code_rev12.ino in Arduino IDE and select Include Library from the Sketch menu option. Select Add .ZIP Library and browse and select the MatrixMaster zip archive. Now Verify and Upload the C++ code to the Arduino Uno's microcontroller.
Step 3: 3D Print the Parts of the Sensor
3D print the parts of the sensor as depicted in the following steps. The
following steps show how to manually build, but with manual construction, dimensions and angles won't be precise. I presently do not own nor can I afford a 3D printer, so I manually constructed it.
Step 4: Construct the Sensor
Cut 2 square pieces from the aluminium foil having breadth of the
plastic cuboid container box and height a little greater than that of the container. Stick each square lamina on a plastic base of exactly equal dimensions as the lamina. Fix these 2 plates to the plastic cuboidal container box at an angle of 75 degrees or (5/12)*PI radians to the horizontal base.
Step 5: Hook Up the Sensor Wires
Connect a wire from from one of
those electrode plates to Pin 2 of the Arduino Uno. Now this electrode plate becomes ELECTRODE_0.
Connect another wire from from the other of those electrode plates to Pin 3 of the Arduino Uno. Now this electrode plate becomes ELECTRODE_1.
Now, fix one wire to the inner side of the plastic cuboidal container box at some distance from ELECTRODE_0. Connect this wire to Pin A1 of the Arduino Uno. Now, this pin becomes OFFSET_0.
Now, fix another wire to the inner side of the plastic cuboidal container box at some distance from ELECTRODE_1. Connect this wire to Pin A2 of the Arduino Uno. Now, this pin becomes OFFSET_1.
Step 6: The Stylus
I used a thin wooden stick. But you can use a sturdy stylus of any non-conductive material. The stylus must be as thin as possible to minimize ripples and disturbance in the water. Fix an insulated wire along its length and strip off just a tiny portion at one end. The coordinates of this tip will be tracked by the 3D sensor. Connect the other end to Pin A0 of the Arduino Uno. Be sure to that the wire is tightly attached to the non-conductive stick and is not separated from the stick at any point. This is to eliminate unnecessary disturbance in the water.
Step 7: Assemble the Components
Attach the Arduino Uno on the lower face of the plastic cuboidal
container box. Now fix this box on a geared DC motor such that the axis of rotation is perpendicular to the horizontal base and passes through the intersection of the diagonals of the horizontal base of the parallelopiped formed by the electrode plates. Connect the geared motor to a 5V 2A AC-DC power adapter.
Step 8: Build Your Client App
Attach your Android smartphone to the plastic container box and use your
client app to accept the x, y, z coordinates from the Arduino Uno. Use these coordinates for your required application.