private void InfoUpdate() { if (wiiDevice.WiimoteState.ExtensionType != ExtensionType.BalanceBoard) { label_Status.Text = "DEVICE IS NOT A BALANCE BOARD..."; return; } label_battery.Text = "Battery: " + wiiDevice.WiimoteState.Battery.ToString("0.0") + "%"; // Get the current raw sensor KG values. var rwWeight = wiiDevice.WiimoteState.BalanceBoardState.WeightKg; var rwTopLeft = wiiDevice.WiimoteState.BalanceBoardState.SensorValuesKg.TopLeft; var rwTopRight = wiiDevice.WiimoteState.BalanceBoardState.SensorValuesKg.TopRight; var rwBottomLeft = wiiDevice.WiimoteState.BalanceBoardState.SensorValuesKg.BottomLeft; var rwBottomRight = wiiDevice.WiimoteState.BalanceBoardState.SensorValuesKg.BottomRight; // The alternative .SensorValuesRaw is not adjusted with 17KG and 34KG calibration data, but does that make for better or worse control? // //var rwTopLeft = wiiDevice.WiimoteState.BalanceBoardState.SensorValuesRaw.TopLeft - wiiDevice.WiimoteState.BalanceBoardState.CalibrationInfo.Kg0.TopLeft; //var rwTopRight = wiiDevice.WiimoteState.BalanceBoardState.SensorValuesRaw.TopRight - wiiDevice.WiimoteState.BalanceBoardState.CalibrationInfo.Kg0.TopRight; //var rwBottomLeft = wiiDevice.WiimoteState.BalanceBoardState.SensorValuesRaw.BottomLeft - wiiDevice.WiimoteState.BalanceBoardState.CalibrationInfo.Kg0.BottomLeft; //var rwBottomRight = wiiDevice.WiimoteState.BalanceBoardState.SensorValuesRaw.BottomRight - wiiDevice.WiimoteState.BalanceBoardState.CalibrationInfo.Kg0.BottomRight; // Show the raw sensor values. label_rwWT.Text = rwWeight.ToString("0.0"); label_rwTL.Text = rwTopLeft.ToString("0.0"); label_rwTR.Text = rwTopRight.ToString("0.0"); label_rwBL.Text = rwBottomLeft.ToString("0.0"); label_rwBR.Text = rwBottomRight.ToString("0.0"); // Prevent negative values by tracking lowest possible value and making it a zero based offset. if (rwTopLeft < naCorners) { naCorners = rwTopLeft; } if (rwTopRight < naCorners) { naCorners = rwTopRight; } if (rwBottomLeft < naCorners) { naCorners = rwBottomLeft; } if (rwBottomRight < naCorners) { naCorners = rwBottomRight; } // Negative total weight is reset to zero as jumping or lifting the board causes negative spikes, which would break 'in use' checks. var owWeight = rwWeight < 0f ? 0f : rwWeight; var owTopLeft = rwTopLeft -= naCorners; var owTopRight = rwTopRight -= naCorners; var owBottomLeft = rwBottomLeft -= naCorners; var owBottomRight = rwBottomRight -= naCorners; // Get offset that would make current values the center of mass. if (setCenterOffset) { setCenterOffset = false; var rwHighest = Math.Max(Math.Max(rwTopLeft, rwTopRight), Math.Max(rwBottomLeft, rwBottomRight)); oaTopLeft = rwHighest - rwTopLeft; oaTopRight = rwHighest - rwTopRight; oaBottomLeft = rwHighest - rwBottomLeft; oaBottomRight = rwHighest - rwBottomRight; } // Keep values only when board is being used, otherwise offsets and small value jitters can trigger unwanted actions. if (owWeight > 0f) { owTopLeft += oaTopLeft; owTopRight += oaTopRight; owBottomLeft += oaBottomLeft; owBottomRight += oaBottomRight; } else { owTopLeft = 0; owTopRight = 0; owBottomLeft = 0; owBottomRight = 0; } label_owWT.Text = owWeight.ToString("0.0"); label_owTL.Text = owTopLeft.ToString("0.0") + "\r\n" + oaTopLeft.ToString("0.0"); label_owTR.Text = owTopRight.ToString("0.0") + "\r\n" + oaTopRight.ToString("0.0"); label_owBL.Text = owBottomLeft.ToString("0.0") + "\r\n" + oaBottomLeft.ToString("0.0"); label_owBR.Text = owBottomRight.ToString("0.0") + "\r\n" + oaBottomRight.ToString("0.0"); // Calculate each weight ratio. var owrPercentage = 100 / (owTopLeft + owTopRight + owBottomLeft + owBottomRight); var owrTopLeft = owrPercentage * owTopLeft; var owrTopRight = owrPercentage * owTopRight; var owrBottomLeft = owrPercentage * owBottomLeft; var owrBottomRight = owrPercentage * owBottomRight; label_owrTL.Text = owrTopLeft.ToString("0.0"); label_owrTR.Text = owrTopRight.ToString("0.0"); label_owrBL.Text = owrBottomLeft.ToString("0.0"); label_owrBR.Text = owrBottomRight.ToString("0.0"); // Calculate balance ratio. var brX = owrBottomRight + owrTopRight; var brY = owrBottomRight + owrBottomLeft; label_brX.Text = brX.ToString("0.0"); label_brY.Text = brY.ToString("0.0"); // Diagonal ratio used for turning on the spot. var brDL = owrPercentage * (owBottomLeft + owTopRight); var brDR = owrPercentage * (owBottomRight + owTopLeft); var brDF = Math.Abs(brDL - brDR); label_brDL.Text = brDL.ToString("0.0"); label_brDR.Text = brDR.ToString("0.0"); label_brDF.Text = brDF.ToString("0.0"); // Pos Calculation var owSum = owTopRight + owBottomRight + owTopLeft + owBottomLeft; var xPos = ((owTopRight + owBottomRight) - (owTopLeft + owBottomLeft)) / owSum; var yPos = ((owTopRight + owTopLeft) - (owBottomRight + owBottomLeft)) / owSum; label_xPos.Text = xPos.ToString("0.0"); label_yPos.Text = yPos.ToString("0.0"); // Collect samples if (buffer.Count == BUFFER_SIZE) { buffer.RemoveAt(0); } buffer.Add(float.IsNaN(xPos) ? 0.0f : xPos); // FFT for (int i = 0; i < complexBuffer.Length; i++) { complexBuffer[i] = new Complex((i < buffer.Count) ? buffer[i] : 0.0, 0.0); } FFT(complexBuffer); // Find max frequency double binAmp = 0.0; int binIndex = -1; for (int i = 0; i < complexBuffer.Length / 2; i++) { double mag = complexBuffer[i].Magnitude; if (mag > binAmp) { binIndex = i; binAmp = mag; } } float sampleRate = 1 / ((float)GUI_UPDATE_MS / 1000.0f); float frequency = (binIndex * (float)sampleRate / 2) / ((float)BUFFER_SIZE / 2); float finalFrequency = frequency / 2; label_xFrequency.Text = finalFrequency.ToString("0.00"); label_xFreqAmp.Text = binAmp.ToString("0.0"); float dcOffset = (float)complexBuffer[0].Real; label_dcOffset.Text = complexBuffer[0].ToString("0.0"); // Convert sensor values into actions. var sendLeft = false; var sendRight = false; var sendForward = false; var sendBackward = false; var sendSprintModifier = false; var sendSneakModifier = false; var sendJump = false; var sendDiagonalLeft = false; var sendDiagonalRight = false; // Convert waddle frequency to actions with modifiers label_sprintFreq.Font = new System.Drawing.Font(label_sprintFreq.Font, System.Drawing.FontStyle.Regular); label_walkFreq.Font = new System.Drawing.Font(label_walkFreq.Font, System.Drawing.FontStyle.Regular); label_sneakFreq.Font = new System.Drawing.Font(label_sneakFreq.Font, System.Drawing.FontStyle.Regular); if (finalFrequency >= Decimal.ToDouble(numericUpDown_sprintFreq.Value)) { sendSprintModifier = true; label_sprintFreq.Font = new System.Drawing.Font(label_sprintFreq.Font, System.Drawing.FontStyle.Bold); } else if (finalFrequency < Decimal.ToDouble(numericUpDown_sprintFreq.Value) && finalFrequency >= Decimal.ToDouble(numericUpDown_walkFreq.Value)) { label_walkFreq.Font = new System.Drawing.Font(label_walkFreq.Font, System.Drawing.FontStyle.Bold); } else if (finalFrequency < Decimal.ToDouble(numericUpDown_walkFreq.Value) && finalFrequency >= Decimal.ToDouble(numericUpDown_sneakFreq.Value)) { sendSneakModifier = true; label_sneakFreq.Font = new System.Drawing.Font(label_sneakFreq.Font, System.Drawing.FontStyle.Bold); } if (frequency > 0) { if (Math.Abs(yPos) >= Decimal.ToDouble(numericUpDown_yDeadzone.Value)) { if (yPos > 0) { sendForward = true; } else { sendBackward = true; } } else { if (Math.Abs(dcOffset) >= Decimal.ToDouble(numericUpDown_strafeThreshold.Value)) { if (dcOffset > 0) { sendRight = true; } else { sendLeft = true; } } } } /* * if (brX < (float)(50 - numericUpDown_TLR.Value)) sendLeft = true; * if (brX > (float)(50 + numericUpDown_TLR.Value)) sendRight = true; * if (brY < (float)(50 - numericUpDown_TFB.Value)) sendForward = true; * if (brY > (float)(50 + numericUpDown_TFB.Value)) sendBackward = true; * * if (brX < (float)(50 - numericUpDown_TMLR.Value)) sendModifier = true; * else if (brX > (float)(50 + numericUpDown_TMLR.Value)) sendModifier = true; * else if (brY < (float)(50 - numericUpDown_TMFB.Value)) sendModifier = true; * else if (brY > (float)(50 + numericUpDown_TMFB.Value)) sendModifier = true; */ // Detect jump but use a time limit to stop it being active while off the board. if (owWeight < 1f) { if (DateTime.UtcNow.Subtract(jumpTime).Seconds < 2) { sendJump = true; } } else { jumpTime = DateTime.UtcNow; } // Check for diagonal pressure only when no other movement actions are active. /* * if (!sendLeft && !sendRight && !sendForward && !sendBackward && brDF > 15) * { * if (brDL > brDR) sendDiagonalLeft = true; * else sendDiagonalRight = true; * } */ // Display actions. label_Status.Text = "Result: "; if (sendForward) { label_Status.Text += "Forward"; } if (sendLeft) { label_Status.Text += "Left"; } if (sendBackward) { label_Status.Text += "Backward"; } if (sendRight) { label_Status.Text += "Right"; } if (sendSprintModifier) { label_Status.Text += " + Sprint Modifier"; } if (sendSneakModifier) { label_Status.Text += " + Sneak Modifier"; } if (sendJump) { label_Status.Text += "Jump"; } if (sendDiagonalLeft) { label_Status.Text += "Diagonal Left"; } if (sendDiagonalRight) { label_Status.Text += "Diagonal Right"; } if (checkBox_DisableActions.Checked) { label_Status.Text += " ( DISABLED )"; } // Send actions. if (!checkBox_DisableActions.Checked) { if (sendLeft) { actionList.Left.Start(); } else { actionList.Left.Stop(); } if (sendRight) { actionList.Right.Start(); } else { actionList.Right.Stop(); } if (sendForward) { actionList.Forward.Start(); } else { actionList.Forward.Stop(); } if (sendBackward) { actionList.Backward.Start(); } else { actionList.Backward.Stop(); } if (sendSprintModifier) { actionList.SprintModifier.Start(); } else { actionList.SprintModifier.Stop(); } if (sendSneakModifier) { actionList.SneakModifier.Start(); } else { actionList.SneakModifier.Stop(); } if (sendJump) { actionList.Jump.Start(); } else { actionList.Jump.Stop(); } if (sendDiagonalLeft) { actionList.DiagonalLeft.Start(); } else { actionList.DiagonalLeft.Stop(); } if (sendDiagonalRight) { actionList.DiagonalRight.Start(); } else { actionList.DiagonalRight.Stop(); } } // Update joystick emulator. if (checkBox_EnableJoystick.Checked) { // Uses Int16 ( -32767 to +32767 ) where 0 is the center. Multiplied by 2 because realistic usage is between the 30-70% ratio. var joyX = (brX * 655.34 + -32767.0) * 2.0; var joyY = (brY * 655.34 + -32767.0) * 2.0; // Limit values to Int16, you cannot just (cast) or Convert.ToIn16() as the value '+ - sign' may invert. if (joyX < short.MinValue) { joyX = short.MinValue; } if (joyY < short.MinValue) { joyY = short.MinValue; } if (joyX > short.MaxValue) { joyX = short.MaxValue; } if (joyY > short.MaxValue) { joyY = short.MaxValue; } // Set new values. joyDevice.SetXAxis(0, (short)joyX); joyDevice.SetYAxis(0, (short)joyY); joyDevice.Update(0); } }
private void InfoUpdate() { if (wiiDevice.WiimoteState.ExtensionType != ExtensionType.BalanceBoard) { label_Status.Text = "DEVICE IS NOT A BALANCE BOARD"; tray.BalloonTipTitle = "Error"; tray.BalloonTipText = "Device is not a Wii Balance Board"; tray.ShowBalloonTip(5000); return; } #region Nerdy maths // Get the current raw sensor KG values. var rwWeight = wiiDevice.WiimoteState.BalanceBoardState.WeightKg; var rwTopLeft = wiiDevice.WiimoteState.BalanceBoardState.SensorValuesKg.TopLeft; var rwTopRight = wiiDevice.WiimoteState.BalanceBoardState.SensorValuesKg.TopRight; var rwBottomLeft = wiiDevice.WiimoteState.BalanceBoardState.SensorValuesKg.BottomLeft; var rwBottomRight = wiiDevice.WiimoteState.BalanceBoardState.SensorValuesKg.BottomRight; // Prevent negative values by tracking lowest possible value and making it a zero based offset. if (rwTopLeft < naCorners) { naCorners = rwTopLeft; } if (rwTopRight < naCorners) { naCorners = rwTopRight; } if (rwBottomLeft < naCorners) { naCorners = rwBottomLeft; } if (rwBottomRight < naCorners) { naCorners = rwBottomRight; } // Negative total weight is reset to zero as jumping or lifting the board causes negative spikes, which would break 'in use' checks. var owWeight = rwWeight < 0f ? 0f : rwWeight; var owTopLeft = rwTopLeft -= naCorners; var owTopRight = rwTopRight -= naCorners; var owBottomLeft = rwBottomLeft -= naCorners; var owBottomRight = rwBottomRight -= naCorners; // Get offset that would make current values the center of mass. if (setCenterOffset) { setCenterOffset = false; var rwHighest = Math.Max(Math.Max(rwTopLeft, rwTopRight), Math.Max(rwBottomLeft, rwBottomRight)); oaTopLeft = rwHighest - rwTopLeft; oaTopRight = rwHighest - rwTopRight; oaBottomLeft = rwHighest - rwBottomLeft; oaBottomRight = rwHighest - rwBottomRight; } // Keep values only when board is being used, otherwise offsets and small value jitters can trigger unwanted actions. if (owWeight > 0f) { owTopLeft += oaTopLeft; owTopRight += oaTopRight; owBottomLeft += oaBottomLeft; owBottomRight += oaBottomRight; } else { owTopLeft = 0; owTopRight = 0; owBottomLeft = 0; owBottomRight = 0; } // Calculate each weight ratio. var owrPercentage = 100 / (owTopLeft + owTopRight + owBottomLeft + owBottomRight); var owrTopLeft = owrPercentage * owTopLeft; var owrTopRight = owrPercentage * owTopRight; var owrBottomLeft = owrPercentage * owBottomLeft; var owrBottomRight = owrPercentage * owBottomRight; // Calculate balance ratio. var brX = owrBottomRight + owrTopRight; var brY = owrBottomRight + owrBottomLeft; if (panel_Config.Visible) { } // Diagonal ratio used for turning on the spot. var brDL = owrPercentage * (owBottomLeft + owTopRight); var brDR = owrPercentage * (owBottomRight + owTopLeft); var brDF = Math.Abs(brDL - brDR); // Convert sensor values into actions. var sendLeft = false; var sendRight = false; var sendForward = false; var sendBackward = false; var sendModifier = false; var sendJump = false; var sendDiagonalLeft = false; var sendDiagonalRight = false; if (brX < (float)(50 - numericUpDown_TLR.Value)) { sendLeft = true; } if (brX > (float)(50 + numericUpDown_TLR.Value)) { sendRight = true; } if (brY < (float)(50 - numericUpDown_TFB.Value)) { sendForward = true; } if (brY > (float)(50 + numericUpDown_TFB.Value)) { sendBackward = true; } if (brX < (float)(50 - numericUpDown_TMLR.Value)) { sendModifier = true; } else if (brX > (float)(50 + numericUpDown_TMLR.Value)) { sendModifier = true; } else if (brY < (float)(50 - numericUpDown_TMFB.Value)) { sendModifier = true; } else if (brY > (float)(50 + numericUpDown_TMFB.Value)) { sendModifier = true; } // Detect jump but use a time limit to stop it being active while off the board. if (owWeight < 1f) { if (DateTime.UtcNow.Subtract(jumpTime).Seconds < 2) { sendJump = true; } } else { jumpTime = DateTime.UtcNow; } // Check for diagonal pressure only when no other movement actions are active. if (!sendLeft && !sendRight && !sendForward && !sendBackward && brDF > 15) { if (brDL > brDR) { sendDiagonalLeft = true; } else { sendDiagonalRight = true; } } // Send actions. if (!checkBox_DisableActions.Checked) { if (sendLeft) { actionList.Left.Start(); } else { actionList.Left.Stop(); } if (sendRight) { actionList.Right.Start(); } else { actionList.Right.Stop(); } if (sendForward) { actionList.Forward.Start(); } else { actionList.Forward.Stop(); } if (sendBackward) { actionList.Backward.Start(); } else { actionList.Backward.Stop(); } if (sendModifier) { actionList.Modifier.Start(); } else { actionList.Modifier.Stop(); } if (sendJump) { actionList.Jump.Start(); } else { actionList.Jump.Stop(); } if (sendDiagonalLeft) { actionList.DiagonalLeft.Start(); } else { actionList.DiagonalLeft.Stop(); } if (sendDiagonalRight) { actionList.DiagonalRight.Start(); } else { actionList.DiagonalRight.Stop(); } } // Update joystick emulator. if (checkBox_EnableJoystick.Checked) { // Uses Int16 ( -32767 to +32767 ) where 0 is the center. Multiplied by 2 because realistic usage is between the 30-70% ratio. var joyX = (brX * 655.34 + -32767.0) * 2.0; var joyY = (brY * 655.34 + -32767.0) * 2.0; // Limit values to Int16, you cannot just (cast) or Convert.ToIn16() as the value '+ - sign' may invert. if (joyX < short.MinValue) { joyX = short.MinValue; } if (joyY < short.MinValue) { joyY = short.MinValue; } if (joyX > short.MaxValue) { joyX = short.MaxValue; } if (joyY > short.MaxValue) { joyY = short.MaxValue; } // Set new values. joyDevice.SetXAxis(0, (short)joyX); joyDevice.SetYAxis(0, (short)joyY); joyDevice.Update(0); } #endregion Nerdy Maths if (panel_Config.Visible) { //Show raw weight in kilogrammes label_rwWT.Text = rwWeight.ToString("0.0") + "kg"; label_rwTL.Text = rwTopLeft.ToString("0.0") + "kg"; label_rwTR.Text = rwTopRight.ToString("0.0") + "kg"; label_rwBL.Text = rwBottomLeft.ToString("0.0") + "kg"; label_rwBR.Text = rwBottomRight.ToString("0.0") + "kg"; //Display Offset values label_owWT.Text = owWeight.ToString("0.0"); label_owTL.Text = owTopLeft.ToString("0.0") + "\r\n" + oaTopLeft.ToString("0.0"); label_owTR.Text = owTopRight.ToString("0.0") + "\r\n" + oaTopRight.ToString("0.0"); label_owBL.Text = owBottomLeft.ToString("0.0") + "\r\n" + oaBottomLeft.ToString("0.0"); label_owBR.Text = owBottomRight.ToString("0.0") + "\r\n" + oaBottomRight.ToString("0.0"); //Display weight ratio label_owrTL.Text = owrTopLeft.ToString("0.0"); label_owrTR.Text = owrTopRight.ToString("0.0"); label_owrBL.Text = owrBottomLeft.ToString("0.0"); label_owrBR.Text = owrBottomRight.ToString("0.0"); //Display balance label_brX.Text = brX.ToString("0.0"); label_brY.Text = brY.ToString("0.0"); //Show Diagonal ratios label_brDL.Text = brDL.ToString("0.0"); label_brDR.Text = brDR.ToString("0.0"); label_brDF.Text = brDF.ToString("0.0"); //Display Output label_Status.Text = "Result: "; if (sendForward) { label_Status.Text += "Forward"; } if (sendLeft) { label_Status.Text += "Left"; } if (sendBackward) { label_Status.Text += "Backward"; } if (sendRight) { label_Status.Text += "Right"; } if (sendModifier) { label_Status.Text += " + Modifier"; } if (sendJump) { label_Status.Text += "Jump"; } if (sendDiagonalLeft) { label_Status.Text += "Diagonal Left"; } if (sendDiagonalRight) { label_Status.Text += "Diagonal Right"; } if (checkBox_DisableActions.Checked) { label_Status.Text += " (DISABLED)"; } } //Change the icon color when Outputting if (sendForward | sendLeft | sendBackward | sendRight | sendDiagonalLeft | sendDiagonalRight) { Icon = Properties.Resources.Balance_Board_Green; tray.Icon = Properties.Resources.Balance_Board_Green; } else { Icon = Properties.Resources.Balance_Board; tray.Icon = Properties.Resources.Balance_Board; } }