0LAUK0 2018Q1 Group 2 - Programming overview: Difference between revisions

From Control Systems Technology Group
Jump to navigation Jump to search
(added information on arduino programming, updated notice and layout)
(→‎Processing: added content to processing section)
Line 5: Line 5:
This page contains an overview of everthing related to the programming of the prototype of [[PRE2018 1 Group2]] for the course Project Robots Everywhere (0LAUK0).
This page contains an overview of everthing related to the programming of the prototype of [[PRE2018 1 Group2]] for the course Project Robots Everywhere (0LAUK0).


= Processing =  
= Processing =
We will use the Processing software sketchbook to develop our face tracking program. We mainly use this software environment because of personal experience, and because it supports all functions that we need in order to make our prototype work properly.


===Face tracking===
Face tracking is achieved using a port of OpenCV (Borenstein, 2013). This library has built-in functions to detect faces. The programmer needs to specify a cascade that will be used to detect faces. We have decided to only look for faces that are looking straight at the screen, as this is most useful for our design.
OpenCV will detect most of the faces in view of the camera most of the time. From this arises a problem: we need to identify the user’s face amongst false positives, such as paintings and lamps that sort of look like a face, or people walking by the user’s desk. Ideally we would use Template Matching to recognize the users face amongst all faces detected by OpenCV.


= Arduino =  
= Arduino =  

Revision as of 23:20, 29 October 2018

Notice

This page will face massive redesigns over the course of the day. Please ignore the 'old layout' section, as its contents will be integrated in the new sections

Notice

This page contains an overview of everthing related to the programming of the prototype of PRE2018 1 Group2 for the course Project Robots Everywhere (0LAUK0).

Processing

We will use the Processing software sketchbook to develop our face tracking program. We mainly use this software environment because of personal experience, and because it supports all functions that we need in order to make our prototype work properly.

Face tracking

Face tracking is achieved using a port of OpenCV (Borenstein, 2013). This library has built-in functions to detect faces. The programmer needs to specify a cascade that will be used to detect faces. We have decided to only look for faces that are looking straight at the screen, as this is most useful for our design.

OpenCV will detect most of the faces in view of the camera most of the time. From this arises a problem: we need to identify the user’s face amongst false positives, such as paintings and lamps that sort of look like a face, or people walking by the user’s desk. Ideally we would use Template Matching to recognize the users face amongst all faces detected by OpenCV.

Arduino

Infrared distance sensors

The Arduino is connected to a Sharp GP2Y0A02YK0F Distance Measuring Sensor Unit. This sensor can detect distances from 20 to 150 cm. It is connected to the Arduino using an analog port on the Arduino Uno. We first convert this analog signal into a voltage, then we use a custom transformation function to approximate the distance in meters. Using a ruler and some math we generated a set of linear equations that match the graphed inverse number of distance (Sharp Corporation, 2006, p. 5).

We tested the reliability of the linear equations by placing the IR sensor on a table with a ruler, and placing an object in front of the sensor at various distances. We then measured the predicted distance. We tried coming up with possible regression models that could predict better than the set of linear equations from our first prototype, but we were unable to find a regression model that predicted better than our initial set of linear equations. We easily achieved a high R-squared of above 0.90, but for each item there was a significant (sometimes up to 15 cm) difference between the distance predicted by the regression and the actual distance. Because of this we stuck with the set of linear equations. The testing data and analysis script used to test possible regressions are available on our google drive project folder. You can also download and use them directly from here.

Serial communication

The serial communication from the Arduino to Processing is pretty much a mirror image of the design of the serial communication from Processing to the Arduino. The Arduino compares text strings that it received against templates for the different operations that it can perform. Two operations are available:

  • If the Arduino receives the command “request: move monitor to x y z”, for some values of x y z, then the program will extract those coordinates and use the motor control functionalities of the other Arduino program to move the monitor in line with our kinematic model.
  • If the Arduino receives the command “request: measure depth”, then the output from the IR-sensor is read, and a new command string for processing is generated that includes the distance in meters. For debug purposes the distance voltage of the IR sensor is also transmitted, but the Processing sketch will ignore this value.

Motor control

For motor control we are using the Arduino and the AccelStepper Library for better control of the 28BYJ 5V stepper motors. AccelStepper Library includes options to set acceleration speed, absolute positioning of the motor based on steps, which are quite useful in the case of a monitor arm.

Arduino Setup

A basic overview of the setup. Numbers are digital pins on the arduino.

BasicArduinoSetup.png

An overview of the code

Initialising digital pins for the motors

Example of initialising digital pins of motor: AccelStepper stepper1(HALFSTEP, motorPin1, motorPin3, motorPin2, motorPin4); The motor stepper1 controls the bottom part of the monitor arm. The motor stepper2 controls the upper part of the monitor arm. The motor stepper3 controls the front piece of the monitor arm.

Initialising starting values of the motor

Setting basic speed, acceleration and current position. The stepper.move(1) has to be called to start motor, without this line of code the motor doesn’t work. Stepper.move(-1), to move 1 step back to position(0).

Initialising Serial with Serial.begin(115200), we use band 115200 for the fastest data processing of Serial commands.

Serial commands contains the absolute position of steps of the motor x and y. This command is parsed into int x and int y. Example 1024, -1024 would mean it is parsed to int x = 1024 and y = -1024. Afterwards stepper1.moveTo(x) and stepper2.moveTo(y), this means that stepper1 moves to the position where the motor would be if it takes 1024 steps from the 0 steps position. Similarly for stepper2 it moves to -1024 steps from the 0 position. Stepper3 tries to point to the front, by taking the opposite position of steps1 and steps2 combined. So stepper3.moveTo(-(x+y)).

Afterwards the amount of steps to the destination position are calculated. This is done in a more complicated manner, because the function distanceToGo() of the AccelStepper library can only be called after the moveTo() or move() functions are called. However, changing the speed and acceleration speed of the motor can’t be done after the move() or moveTo() functions are called. The distances are needed to calculate how fast the motors have to go compared to the other motors to finish at the same time. The speed of the motor can’t go much above 1000 before it becomes unstable, so it is limited to 1024. The speed of the motor can’t go below 32, because the speed becomes incredibly slow and somehow doesn’t finish at the same time as the other motors do.

References

  • Sharp Corporation. (2006). Sharp_Gp2Y0a02Yk0F_E. Retrieved from [1]


Layout of the ideal Processing sketch for our prototype

Processing code layout

User object has

  • Average location (x,y,z detected by OpenCV and IR)
  • Ideal location (x,y,z of center of screen)
  • Max RSI preventive compliant posture (how extreme can the user posture be without breaking the RSI prevention rules)
  • Time spent in current posture
  • Pixel map of face at startup
  • Precision measure of repeated observations of face pixel map.


Cameras have

  • Conversion metrics to transform pixels into angles into meters


Arduino IR has

  • Conversion metric to transform voltage into meters


At startup

  • User's face will be around their ideal location, capture the pixel map of the face detected around this location
  • Load equipment and user attributes mentioned above.

At a predefined interval - call openCV to detect faces

  • If no face is detected, maintain the average face location calculated from previous face detections
  • If one face is detected, compare to face pixel map
    • If similarity is too low, maintain the average face location calculated from previous face detections
    • If similarity is high, update the average face location
  • If multiple faces are detected, compare detected faces to face pixel map
    • If there is no match, maintain the average face location calculated from previous face detections.
    • If there is one match, update average face location using this face.
    • If there are multiple matches, choose faces closest to average face location and update average face location using this face.
  • If the current location of the face is significantly different from the average face location:
    • Start counting time that this new posture is held:
      • If time is very low: it was a split movement, no long term change in posture -> ignore
      • If time is long: it is a long term change in posture -> move monitor
    • If detected as posture change:
      • Face has moved up or down:
        • Calculate delta_x, delta_y. give command to move monitor, when the monitor is in front of the user, calculate delta_z using the arduino IR. Give command to move monitor in z direction if delta_z > threshold
      • Detected face width has changed: (user moved forward or backward)
        • Calculate delta_z using the arduino IR. Give command to move monitor in z direction if delta_z > threshold
      • Determine if new posture is RSI preventive compliant

Keep track of how long a posture is held

  • If posture is RSI prevention compliant: held for too long, notify user to move
  • If posture is not RSI prevention compliant: use a much shorter time threshold, notify user sooner