package com.dronecontrol.perceptual.helpers;
import com.google.common.collect.Lists;
import com.dronecontrol.perceptual.data.body.Coordinate;
import com.dronecontrol.perceptual.data.body.Hand;
import java.util.Collection;
public class CoordinateCalculator {
private static final float MIN_ROLL = 0.2f;
private static final float MIN_PITCH = 0.2f;
public static final float MIN_YAW = 0.2f;
private static final float MIN_HEIGHT = 0.2f;
private static final float MAX_HEIGHT = 2.0f;
private static final float MAX_ANGLE_DIFFERENCE = 35;
private static final float ANGLE_LOWER_VALUE = -10;
private Coordinate leftHandReferenceCoordinate;
private Coordinate rightHandReferenceCoordinate;
private float yaw;
private float securityScaleBuffer = 0.8f;
private float maxYaw = 0.2f * securityScaleBuffer;
private float roll;
private float maxRoll = 0.2f * securityScaleBuffer;
private float pitch;
private float maxPitch = 0.2f * securityScaleBuffer;
private float currentHeight;
private float heightDelta;
private Collection<CoordinateListener> coordinateListeners = Lists.newArrayList();
public void setLeftHandReferenceCoordinate(Coordinate leftHandReferenceCoordinate) {
this.leftHandReferenceCoordinate = leftHandReferenceCoordinate;
}
public void setRightHandReferenceCoordinate(Coordinate rightHandReferenceCoordinate) {
this.rightHandReferenceCoordinate = rightHandReferenceCoordinate;
}
public void setCurrentHeight(float currentHeight) {
this.currentHeight = currentHeight;
}
public void calculateMoves(Hand leftHand, Hand rightHand) {
calculateYaw(leftHand, rightHand);
calculateRoll(leftHand, rightHand);
calculatePitch(leftHand, rightHand);
calculateDesiredHeight(leftHand, rightHand);
for (CoordinateListener coordinateListener : coordinateListeners) {
coordinateListener.onCoordinate(roll, pitch, yaw, heightDelta);
}
}
private void calculateDesiredHeight(Hand leftHand, Hand rightHand) {
double currentAngle = getAngle(leftHand.getCoordinate(), rightHand.getCoordinate());
double initialAngle = getAngle(leftHandReferenceCoordinate, rightHandReferenceCoordinate);
double angleDifference = (currentAngle - initialAngle);
float desiredHeight = (float) ((angleDifference - ANGLE_LOWER_VALUE) / MAX_ANGLE_DIFFERENCE) * MAX_HEIGHT;
desiredHeight = Math.max(MIN_HEIGHT, desiredHeight);
desiredHeight = Math.min(MAX_HEIGHT, desiredHeight);
this.heightDelta = (desiredHeight - currentHeight) / MAX_HEIGHT;
}
private double getAngle(Coordinate leftHandCoordinate, Coordinate rightHandCoordinate) {
float y = (leftHandCoordinate.getY() + rightHandCoordinate.getY()) / 2;
float z = (leftHandCoordinate.getZ() + rightHandCoordinate.getZ()) / 2;
return Math.toDegrees(Math.atan(y / z));
}
private void calculatePitch(Hand leftHand, Hand rightHand) {
float pitch = ((leftHand.getCoordinate().getZ() - leftHandReferenceCoordinate.getZ()) +
(rightHand.getCoordinate().getZ() - rightHandReferenceCoordinate.z)) / 2;
//Scale pitch using maxPitch
pitch = pitch / maxPitch;
//pitch = pitch * Math.abs(pitch);
if (Math.abs(pitch) <= 0.2) {
pitch = 0;
}
pitch = pitch - Math.signum(pitch) * MIN_PITCH;
//logger.debug(String.format("Pitch-Max: [%2.3f], Pitch-In: [%2.3f], Pitch-Out: [%2.3f]", maxPitch, tmp, pitch));
this.pitch = pitch;
}
private void calculateRoll(Hand leftHand, Hand rightHand) {
float roll = leftHand.getCoordinate().getY() - rightHand.getCoordinate().getY();
if (Math.abs(roll) >= Math.abs(maxRoll)) {
maxRoll = Math.abs(roll);
}
//Scale roll using maxRoll
roll = roll / maxRoll;
//roll = roll * Math.abs(roll);
if (Math.abs(roll) <= MIN_ROLL) {
roll = 0;
}
roll = roll - Math.signum(roll) * MIN_ROLL;
//logger.debug(String.format("Roll-Max: [%2.3f], Roll-In: [%2.3f], Roll-Out: [%2.3f]", maxRoll, tmp, roll));
this.roll = roll;
}
private void calculateYaw(Hand leftHand, Hand rightHand) {
float yaw = rightHand.getCoordinate().getZ() - leftHand.getCoordinate().getZ();
//Scale pitch using maxPitch
yaw = yaw / maxYaw;
if (Math.abs(yaw) <= MIN_YAW) {
yaw = 0;
} else {
yaw = yaw - Math.signum(yaw) * MIN_YAW;
}
System.out.println(String.format("Yaw-Max: [%2.3f], Yaw-Out: [%2.3f]", maxYaw, yaw));
this.yaw = yaw;
}
public float getYaw() {
return this.yaw;
}
public float getRoll() {
return this.roll;
}
public float getPitch() {
return this.pitch;
}
public float getHeightDelta() {
return this.heightDelta;
}
public void addCoordinateListener(CoordinateListener coordinateListener) {
coordinateListeners.add(coordinateListener);
}
public boolean hasHandReferences() {
return (rightHandReferenceCoordinate != null) && (leftHandReferenceCoordinate != null);
}
}