close-circle
Close
0%
0%

Low Cost Accurate 3D Positioning

A ridiculously low cost sensor for real-time tracking of precise coordinates of the tip of a stylus, in confined 3D space.

Similar projects worth following
close
The basic idea behind this 3D sensor is the use of a parallelopiped water container as a water potentiometer device. This principle is employed to develop a ridiculously low cost sensor for real-time tracking of the precise coordinates of the tip of a stylus, in confined 3D space (within the dimensions of a container).

The Challenge

The 3D positioning and gesture tracking technology incorporated in all of today's sensors, such as the Kinect 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 -

  1. costs merely 6.4%, ($7.6, i.e, counterfeit Arduino Uno + geared motor) compared to 2 x Oculus Sensor (2 x $59 as stated in https://www.oculus.com/accessories/), and also much less than other IR cameras/sensors.
  2.  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.
  3.  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.
  4. can be reconstructed from scratch in a mere 10 minutes, and has very simple schematics and build design.
  5. 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

  1. Water potentiometer gives the voltage at tip of the stylus.
  2. Voltage gives a plane containing the tip of the stylus.
  3. Geared DC motor rotates the sensor to give 3 different voltages for 3 different angular positions, for the same fixed stylus tip.
  4. 3 different voltages implies 3 non-parallel plane equations.
  5. 3 non-parallel planes intersect at a unique point.
  6. x, y, z coordinates of that point is the stylus tip's location.

 Detailed Explanation of Tracking Algorithm 

(This is not a video of the final prototype. It just demonstrates the water potentiometer technique used in this project and practically verifies the below differential equations.)

The basic idea behind this sensor is the use of a parallelopiped water container as a water potentiometer device. It is similar to a 3-pin slide pot used in electronic circuits, with the 2 aluminium electrodes equivalent to the 2 end pins of a slide pot, and the stylus equivalent to the middle pin (voltage output) of a slide potentiometer. 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 -

  1. The microcontroller C++ code constantly keeps swapping over the polarity...
Read more »

3d_sensor.ino

12th revision of Arduino C++ code for Arduino Uno's Atmega328 microcontroller. Download the Arduino IDE from https://www.arduino.cc/en/Main/Software

x-arduino - 14.50 kB - 11/22/2017 at 20:31

download-circle
Download

water_potentiometer.ino

Arduino C++ code for DIY Water Potentiometer.

ino - 2.80 kB - 11/16/2017 at 08:51

download-circle
Download

MatrixMath-master.zip

MatrixMath C++ library for matrix multiply and matrix invert operations in the 3D positioning algorithm. MatrixMath C++ library is licensed under GPL2. Github repository - https://github.com/codebndr/MatrixMath

Zip Archive - 11.16 kB - 10/13/2017 at 17:15

download-circle
Download

3d_sensor_schematic.PNG

Snapshot of 2nd revision of circuit schematic for the 3D sensor.

Portable Network Graphics (PNG) - 45.32 kB - 11/10/2017 at 19:15

eye
Preview
download-circle
Download

3d_sensor_schematic.fzz

2nd revision of Fritzing circuit schematic for the 3D sensor. Fritzing software download link - http://fritzing.org/download/

fzz - 3.11 kB - 11/10/2017 at 19:19

download-circle
Download

View all 7 files

  • 1 × Arduino Uno R3 counterfeit Arduino Uno board costing $6.2
  • 1 × Geared DC motor 5V RPM=20
  • 1 × 5V AC-DC power adapter current rating = 2 A
  • 1 × aluminium foil kitchen aluminium foil
  • 1 × 3D printed 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

  • No 3D printer, so prototype build halted

    Sumit Aich10/20/2017 at 21:26 0 comments

    After a lot of modifications and reconstructing the sensor numerous times ,using spare parts, I was not able to precisely build the prototype to exact dimensions and angles as stated in the design.

    This was affecting tracking precision a lot. The parts of the sensor MUST BE 3D printed. I presently do not own nor can I afford a 3D printer, so I'll halt this prototype construction here and resume once I'm in possession of one.

  • Use the thinnest possible stylus

    Sumit Aich10/14/2017 at 07:56 0 comments

    Sudden movement of the stylus are causing ripples or disturbance in water which will hamper tacking precision of the coordinates of the stylus tip.

    I need to reduce subtle variations in the voltage read at SENSOR_ADC pin. Therefore, the stylus must be as thin as possible to minimize ripples or disturbance of  the water.

    I used a thin wooden stylus. 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.

  • Remarks and Drawbacks

    Sumit Aich10/09/2017 at 03:21 3 comments

    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.

    Flow of data from 3D sensor to Client App


  • Started testing the 3D sensor

    Sumit Aich10/08/2017 at 02:28 0 comments

    I just now began the testing and debugging of the 3D sensor.

  • Measuring angular velocity of motor

    Sumit Aich10/07/2017 at 17:36 0 comments

    Since a constant load(constant moment of inertia of the Sensor + Arduino Uno + Android smartphone), is attached to the geared motor and a constant voltage drop of 5V is applied across the motor, its angular velocity remains constant with respect to time and angular position. Now, I'm measuring the angular velocity of the geared DC motor attached to the sensor. The magnitude of its angular velocity in radians per microseconds is 0.00418  .

  • Need to further minimize electrolysis​

    Sumit Aich10/07/2017 at 01:22 0 comments

      I need to further minimize electrolysis of water in the 3D sensor.

      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 -

      1. The microcontroller C++ code constantly keeps swapping over the polarity of voltage drop across the water, to cancel out the disturbance in its composition.
      2. 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 adaptions, 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.

  • Completed building the circuit

    Sumit Aich10/01/2017 at 12:08 0 comments

     Today, I hooked up the sensor input and output lines to the Arduino Uno R3 board.

  • Working on Fritzing schematics

    Sumit Aich10/01/2017 at 12:06 0 comments

    Today I'm working on Fritzing circuit schematics.

    Licensing

    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. https://github.com/fritzing/fritzing-app.


  • Finished debugging the C++ code

    Sumit Aich10/01/2017 at 12:03 0 comments

    Today I finished debugging and commenting the Arduino C++ code for the Atmega 328 microcontroller. This is the 12th and final revision of Arduino C++ code.


    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 -

    258
    <x>
    <y>
    <z>

    DATATYPE: x, y, z are all in float

    RANGE:  -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".


    C++ code

    #include <MatrixMath.h>
    #define ELECTRODE_0 2        //left water electrode 
    #define ELECTRODE_1 3        //right water electrode
    #define SENSOR_ADC  0        //metal pin attached to stylus tip (Vout of water potentiometer)
    #define OFFSET_0    1        //left offset pin
    #define OFFSET_1    2        //right offset pin
    #define SIN_A         0.96592     //sine of base angle of parallelopiped ((5/12)*PI radians )
    #define MCOS_A       -0.25881    //negative of cosine of base angle of parallelopiped (5*PI/12 radians or 75 degrees)
    #define ANGULAR_VELO  0.00418 //angular velocity of geared motor in radian per microsecond
    #define BAUDRATE      2000000
    boolean x;
    unsigned long time_1 ;  //time in microseconds since boot
    float theta_0,          //first angular position of sensor
          theta_1,          //second angular position of sensor
          theta_2,          //third angular position of sensor
          coord[3],         //position vector of stylus tip
          mat_a[3][3],      //matrix of direction cosines of normal vectors to the 3 planes
          mat_b[3],         //matrix of perpendicular distances to 3 planes from origin
          var0_0,
          var0_1,
          var0_2,
          var1_0,
          var1_1,
          var1_2,
          var2_0,
          var2_1,
          var2_2;
    int read_0,     //stylus tip voltage at first angular position of sensor
        read_1,     //stylus tip voltage at second angular position of sensor
        read_2,     //stylus tip voltage at third angular position of sensor
        nc_0,       //whether stylus tip was inside or outside water at first angular position of sensor(1023 stands for "INSIDE" and <1023 stands for "OUTSIDE")
        nc_1,       //whether stylus tip was inside or outside water at second angular position of sensor(1023 stands for "INSIDE" and <1023 stands for "OUTSIDE")
        nc_2,       //whether stylus tip was inside or outside water at third angular position of sensor(1023 stands for "INSIDE" and <1023 stands for "OUTSIDE")
        offset_0,   //voltage at left offset pin
        offset_1;   //voltage at right offset pin
    void setup() {
      pinMode(ELECTRODE_0, OUTPUT);
      pinMode(ELECTRODE_1, OUTPUT);
      //set both water electrodes to +5V to pause electrolysis for a while
      digitalWrite(ELECTRODE_0, 1);
      digitalWrite(ELECTRODE_1, 1);
      x = 0;
      nc_0 = nc_1 = nc_2 = 1023;
      Serial.begin(BAUDRATE);
      analogReference(DEFAULT);
    }
    void loop() {
      //Phase 1
      //swap polarity of voltage drop across water
      digitalWrite(ELECTRODE_0, 0);
      time_1 = micros();
      read_0 = analogRead(SENSOR_ADC);
      offset_0 = analogRead(OFFSET_0);
      offset_1 = analogRead(OFFSET_1);
      digitalWrite(ELECTRODE_0, 1);
      nc_0 = analogRead(SENSOR_ADC);
      //check whether stylus tip is inside or outside water
      if (nc_0 != 1023 || nc_1 != 1023 || nc_2 != 1023) {
        coord[0] = 257.00;//257.00 stands for "stylus tip outside water"
        coord[1] = 257.00;//257.00 stands for "stylus tip outside water"
        coord[2] =...
    Read more »

  • Finished designing on paper

    Sumit Aich09/25/2017 at 13:32 0 comments

      Today I finished designing the project on paper

      Brief Explanation of Tracking Algorithm

      1. Water potentiometer gives the voltage at tip of the stylus.
      2. Voltage gives a plane containing the tip of the stylus.
      3. DC motor rotates the sensor to give 3 different voltages for the same fixed tip.
      4. 3 different voltages implies 3 non-parallel plane equations.
      5. 3 non-parallel planes intersect at a unique point.
      6. x,y,z coordinates of that point is the stylus tip's location.

      Flow of data from 3D sensor to Client App

View all 10 project logs

  • 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 its dimensions= 20cm x 10cm x 8cm )
    • 5V AC-DC power adapter ( current rating= 2 A)
  • 2
    Upload Arduino C++ code to Arduino Uno

    Download the Arduino IDE from https://www.arduino.cc/en/main/software .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.

  • 3
    Construct The Sensor

    3D print the paralleopiped water container of the sensor as depicted in the next 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.

    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.

View all 7 instructions

Enjoy this project?

Share

Discussions

Paul Crouch wrote 10/03/2017 at 12:51 point

Got any scribbles, diagrams or photos?

  Are you sure? yes | no

Sumit Aich wrote 10/07/2017 at 17:40 point

Just posted a Fritzing circuit schematic

  Are you sure? yes | no

Sumit Aich wrote 10/14/2017 at 08:12 point

also added a flowchart depicting the flow of data from the 3D sensor to the client app

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates