AutoBone: Load multiple recordings, fine-tune values and extract ratios, fix restricted values from getting stuck

This commit is contained in:
ButterscotchVanilla
2021-08-12 19:30:36 -04:00
parent a52384de2e
commit 760dbfa5b9
2 changed files with 93 additions and 24 deletions

View File

@@ -18,6 +18,7 @@ import io.eiren.gui.autobone.PoseFrame;
import io.eiren.gui.autobone.PoseRecordIO;
import io.eiren.util.StringUtils;
import io.eiren.util.ann.ThreadSafe;
import io.eiren.util.collections.FastList;
import io.eiren.vr.VRServer;
import io.eiren.vr.processor.HumanSkeletonWithLegs;
import io.eiren.vr.processor.HumanSkeleton;
@@ -125,6 +126,25 @@ public class SkeletonConfig extends EJBag {
throw new NullPointerException("Reading frames from \"" + loadRecording.getPath() + "\" failed...");
}
FastList<PoseFrame> newFrames = new FastList<PoseFrame>(frames);
int recordNumber = 1;
for (;;) {
File loadRecordingI = new File("ABRecording_Load" + recordNumber++ + ".abf");
if (loadRecordingI.exists()) {
PoseFrame[] framesI = PoseRecordIO.readFromFile(loadRecordingI);
if (framesI == null) {
throw new NullPointerException("Reading frames from \"" + loadRecordingI.getPath() + "\" failed...");
}
newFrames.addAll(framesI);
} else {
frames = newFrames.toArray(frames);
break;
}
}
autoBone.setFrames(frames);
setText("Wait");

View File

@@ -15,7 +15,7 @@ import io.eiren.vr.processor.HumanSkeletonWithWaist;
public class AutoBone {
protected final static int MIN_DATA_DISTANCE = 1;
protected final static int MAX_DATA_DISTANCE = 1000;
protected final static int MAX_DATA_DISTANCE = 200;
protected final static int NUM_EPOCHS = 20;
@@ -28,6 +28,18 @@ public class AutoBone {
protected final static float HEADSET_HEIGHT_RATIO = 0.91f;
protected final static float CHEST_WAIST_RATIO_MIN = 0.2f;
protected final static float CHEST_WAIST_RATIO_MAX = 0.6f;
protected final static float HIP_MIN = 0.08f;
protected final static float HIP_WAIST_RATIO_MAX = 0.4f;
protected final static float LEG_WAIST_RATIO_MIN = 0.5235f;
protected final static float LEG_WAIST_RATIO_MAX = 1.7235f;
protected final static float KNEE_LEG_RATIO_MIN = 0.42f;
protected final static float KNEE_LEG_RATIO_MAX = 0.58f;
protected final VRServer server;
HumanSkeletonWithLegs skeleton = null;
@@ -161,17 +173,26 @@ public class AutoBone {
}
public void processFrames() {
processFrames(NUM_EPOCHS, true, INITIAL_ADJUSTMENT_RATE, ADJUSTMENT_RATE_DECAY, MIN_DATA_DISTANCE, MAX_DATA_DISTANCE);
}
public void processFrames(int epochs, boolean calcInitError) {
processFrames(epochs, calcInitError, INITIAL_ADJUSTMENT_RATE, ADJUSTMENT_RATE_DECAY, MIN_DATA_DISTANCE, MAX_DATA_DISTANCE);
}
public void processFrames(int epochs, boolean calcInitError, float adjustRate, float adjustRateDecay) {
processFrames(epochs, calcInitError, adjustRate, adjustRateDecay, MIN_DATA_DISTANCE, MAX_DATA_DISTANCE);
}
public void processFrames(int epochs, boolean calcInitError, float adjustRate, float adjustRateDecay, int minDataDist, int maxDataDist) {
Set<Entry<String, Float>> configSet = configs.entrySet();
SimpleSkeleton skeleton1 = new SimpleSkeleton(configSet);
SimpleSkeleton skeleton2 = new SimpleSkeleton(configSet);
int epochs = NUM_EPOCHS;
int epochCounter = -1;
int epochCounter = calcInitError ? -1 : 0;
int cursorOffset = MIN_DATA_DISTANCE;
float adjustRate = INITIAL_ADJUSTMENT_RATE;
int cursorOffset = minDataDist;
float sumError = 0f;
int errorCount = 0;
@@ -188,7 +209,7 @@ public class AutoBone {
for (;;) {
// Detect end of iteration
if (cursorOffset >= frames.length || cursorOffset > MAX_DATA_DISTANCE) {
if (cursorOffset >= frames.length || cursorOffset > maxDataDist) {
epochCounter++;
// Calculate average error over the epoch
@@ -204,8 +225,8 @@ public class AutoBone {
break;
} else {
// Reset cursor offset and decay the adjustment rate
cursorOffset = MIN_DATA_DISTANCE;
adjustRate /= ADJUSTMENT_RATE_DECAY;
cursorOffset = minDataDist;
adjustRate /= adjustRateDecay;
}
}
@@ -256,7 +277,7 @@ public class AutoBone {
// LogManager.log.info("[AutoBone] Current position error: " + error);
// }
for (Entry<String, Float> entry : configs.entrySet()) {
entryLoop: for (Entry<String, Float> entry : configs.entrySet()) {
// Skip adjustment if the epoch is before starting (for logging only)
if (epochCounter < 0) {
break;
@@ -265,7 +286,7 @@ public class AutoBone {
float originalLength = entry.getValue();
// Try positive and negative adjustments
for (int i = 0; i < 2; i++) {
posNegAdj: for (int i = 0; i < 2; i++) {
float curAdjustVal = i == 0 ? adjustVal : -adjustVal;
float newLength = originalLength + curAdjustVal;
@@ -274,34 +295,62 @@ public class AutoBone {
continue;
}
// Detect and skip invalid values
// Detect and fix invalid values, skipping adjustment
Float val;
switch (entry.getKey()) {
case "Chest":
val = configs.get("Waist");
if (val == null || newLength <= 0.2f * val || newLength >= 0.6f * val) {
continue;
if (val == null || newLength <= CHEST_WAIST_RATIO_MIN * val || newLength >= CHEST_WAIST_RATIO_MAX * val) {
entry.setValue(Math.min(Math.max(newLength, CHEST_WAIST_RATIO_MIN * val), CHEST_WAIST_RATIO_MAX * val));
// If bone length hasn't been changed on skeleton, skip right to next entry
if (i > 0) {
break posNegAdj;
} else {
continue entryLoop;
}
}
break;
case "Hips width":
val = configs.get("Waist");
if (val == null || newLength < 0.08f || newLength >= 0.4f * val) {
continue;
}
break;
if (val == null || newLength < HIP_MIN || newLength >= HIP_WAIST_RATIO_MAX * val) {
entry.setValue(Math.min(Math.max(newLength, HIP_MIN), HIP_WAIST_RATIO_MAX * val));
case "Knee height":
val = configs.get("Legs length");
if (val == null || newLength <= 0.375f * val || newLength >= 0.625f * val) {
continue;
// If bone length hasn't been changed on skeleton, skip right to next entry
if (i > 0) {
break posNegAdj;
} else {
continue entryLoop;
}
}
break;
case "Legs length":
val = configs.get("Waist");
if (val == null || newLength <= 0.5235f * val || newLength >= 1.7235f * val) {
continue;
if (val == null || newLength <= LEG_WAIST_RATIO_MIN * val || newLength >= LEG_WAIST_RATIO_MAX * val) {
entry.setValue(Math.min(Math.max(newLength, LEG_WAIST_RATIO_MIN * val), LEG_WAIST_RATIO_MAX * val));
// If bone length hasn't been changed on skeleton, skip right to next entry
if (i > 0) {
break posNegAdj;
} else {
continue entryLoop;
}
}
break;
case "Knee height":
val = configs.get("Legs length");
if (val == null || newLength <= KNEE_LEG_RATIO_MIN * val || newLength >= KNEE_LEG_RATIO_MAX * val) {
entry.setValue(Math.min(Math.max(newLength, KNEE_LEG_RATIO_MIN * val), KNEE_LEG_RATIO_MAX * val));
// If bone length hasn't been changed on skeleton, skip right to next entry
if (i > 0) {
break posNegAdj;
} else {
continue entryLoop;
}
}
break;
}