0LAUK0 2018Q1 Group 2 - Programming overview

From Control Systems Technology Group
Jump to navigation Jump to search

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

Processing

Arduino

Infrared distance sensors

Serial communication

Motor control (Hans's part)

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

alt text

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

list of references here, in alphabetical order


Old layout - will be deleted eventually

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