/// <summary> Used to call the GloveDetected event. </summary> private void OnGloveDetected(SenseGlove glove, int gloveIndex) { if (GloveDetected != null) { GloveDetected(this, new GloveDetectedArgs(glove, gloveIndex)); } }
//-------------------------------------------------------------------------------------------------------------------------- // Connection Methods /// <summary> Link this Sense Glove to one of the SenseGlove_Manager's detected gloves. </summary> /// <param name="gloveIndex"></param> public bool LinkToGlove(int gloveIndex) { if (!this.IsLinked) { this.trackedGloveIndex = gloveIndex; this.actualTrackedIndex = gloveIndex; this.linkedGlove = SenseGlove_DeviceManager.GetSenseGlove(gloveIndex); this.linkedGlove.OnFingerCalibrationFinished += LinkedGlove_OnCalibrationFinished; //TODO: Subscribe to more events if needed //uodating once so glovedata is available, but not through the UpdateHand command, as that one needs the glove to already be connected. SenseGloveCs.GloveData rawData = this.linkedGlove.Update(UpdateLevel.HandPositions, this.solver, this.limitFingers, this.updateWrist, new Quat(0, 0, 0, 1), false); this.linkedGloveData = new SenseGlove_Data(rawData); this.OnGloveLink(); //Fire glove linked event. return(true); } else { Debug.LogWarning("Could not Link the Sense Glove because it has already been assigned. Unlink it first bu calling the UnlinkGlove() Method."); } return(false); }
public void SetBrakeBuzz(int[] ffb, int[] buzz) { if (CanTestBuzzMotors && CanTestFFB) { int[] FFBcmd = FFBLvls; for (int f = 0; f < 5 && f < ffb.Length; f++) //ensures it works even if levels is not large enough { FFBcmd[f] = Mathf.Clamp(ffb[f], 0, 100); } FFBLvls = FFBcmd; //updates latest int[] buzzCmd = BuzzMotorLvls; for (int f = 0; f < 5 && f < buzz.Length; f++) //ensures it works even if levels is not large enough { buzzCmd[f] = Mathf.Clamp(buzz[f], 0, 100); } BuzzMotorLvls = buzzCmd; //updates latest SenseGlove iGlove = (SenseGlove)senseGlove.GetInternalObject(); if (iGlove != null) { iGlove.SendBrakeBuzz(FFBcmd, buzzCmd); } else { Debug.Log("Could not send commands because we have no Glove"); } } }
/// <summary> /// Disconnect and retry the connecting to the SenseGlove, /// such as when a different glove is connected or when the (manual) connection is lost. /// </summary> public void RetryConnection() { this.Disconnect(); if (this.connectionMethod != ConnectionMethod.HardCoded) { if (!SenseGloveCs.DeviceScanner.IsScanning()) { SenseGloveCs.DeviceScanner.pingTime = 200; SenseGloveCs.DeviceScanner.scanDelay = 500; SenseGloveCs.DeviceScanner.StartScanning(true); } } else //we're dealing with a custom connection! { if (canReport) { SenseGlove_Debugger.Log("Attempting to connect to " + this.address); } Communicator PCB = null; if (this.address.Contains("COM")) //Serial connections { if (this.address.Length > 4 && this.address.Length < 6) { this.address = "\\\\.\\" + this.address; } PCB = new SerialCommunicator(this.address); } if (PCB != null) { PCB.Connect(); if (PCB.IsConnected()) { this.glove = new SenseGlove(PCB); this.glove.OnFingerCalibrationFinished += Glove_OnFingerCalibrationFinished; } else if (canReport) { SenseGlove_Debugger.Log("ERROR: Could not connect to " + this.address); canReport = false; } } else if (canReport) { SenseGlove_Debugger.Log("ERROR: " + this.address + " is not a valid address."); canReport = false; } } this.elapsedTime = 0; this.standBy = false; }
/// <summary> Checks for any new events that have come in from the SenseGloveCs library. </summary> /// <remarks> Events are queued and fired here so that they are Unity-Safe: They could be fired from asynchronous worker threads, /// and certain Unity functions are only accessible from this main thread. </remarks> private void CheckEventQueue() { //New gloves detected since the last Update if (this.queuedGloves.Count > 0) { for (int i = 0; i < this.queuedGloves.Count; i++) { SenseGlove detectedGlove = this.queuedGloves[i]; //keep a refrence here, since the RemoveAt may make it go out of scope. Debug.Log("Found a new unattended Glove: " + detectedGlove.DeviceID()); this.AssignNewGlove(detectedGlove); } this.queuedGloves.Clear(); //clear after we're done(?) } }
/// <summary> /// Disconnect the glove and stop updating until the RetryConnection is called. /// This allows a developer to change the communication variables before calling the RetryConnection method. /// </summary> public void Disconnect() { if (glove != null) { this.glove.OnFingerCalibrationFinished -= Glove_OnFingerCalibrationFinished; } this.gloveReady = false; if (this.gloveData != null) { SenseGlove_Manager.SetUsed(this.gloveData.deviceID, false); } this.glove = null; //The DeviceScanner will still keep them, specifically their communicator, in memory. this.standBy = true; }
//-------------------------------------------------------------------------------------------------------------------------- // Connection Methods protected override bool CanLinkTo(IODevice device) { if (device != null && device is SenseGloveCs.SenseGlove) { if (this.connectionMethod == ConnectionMethod.NextGlove) { return(true); } SenseGlove glove = ((SenseGlove)device); return((glove.IsRight() && this.connectionMethod == ConnectionMethod.NextRightHand) || (!glove.IsRight() && this.connectionMethod == ConnectionMethod.NextLeftHand)); } return(false); }
protected override void SetupDevice() { this.linkedGlove = (SenseGlove)this.linkedDevice; //this.linkedGlove.OnFingerCalibrationFinished += LinkedGlove_OnCalibrationFinished; //uodating once so glovedata is available, but not through the UpdateHand command, as that one needs the glove to already be connected. SenseGloveCs.GloveData rawData = this.linkedGlove.GetData(false); this.linkedGloveData = new SenseGlove_Data(rawData); //Device has been linked, now retrieve calibration. string serialized; if (SG.Calibration.SG_CalibrationStorage.LoadInterpolation(SenseGloveCs.DeviceType.SenseGlove, linkedGloveData.gloveSide, out serialized)) { //Debug.Log("Loaded Calibration for the " + (linkedGloveData.gloveSide == GloveSide.LeftHand ? "Left Hand" : "Right Hand")); linkedGlove.SetInterpolationValues(serialized); //sets internal values } }
/// <summary> Unlink this glove from the manager. </summary> public void UnlinkGlove() { if (this.IsLinked) //only is we are actually linked. { this.CancelCalibration(); this.wasConnected = false; this.OnGloveUnLink(); //fire unlink event this.actualTrackedIndex = -1; this.trackedGloveIndex = -1; if (this.linkedGlove != null) { this.linkedGlove.OnFingerCalibrationFinished -= LinkedGlove_OnCalibrationFinished; } this.linkedGlove = null; } }
/// <summary> Attempt to link a new glove to one of our assigned SenseGlove_Objects. Fire a GloveDetected event afterwards.? </summary> /// <param name="glove"></param> private void AssignNewGlove(SenseGlove glove) { if (GetGloveIndex(glove.DeviceID()) < 0) //It is a new glove { SenseGlove_DeviceManager.detectedGloves.Add(glove); SenseGlove_DeviceManager.gloveLinked.Add(false); int index = detectedGloves.Count - 1; bool linked = false; bool isRight = glove.IsRight(); //attempt to assign it to existing SenseGlove_Objects? for (int i = 0; i < this.senseGloves.Count; i++) { if (this.senseGloves[i] != null) { if (!this.senseGloves[i].IsLinked && SenseGlove_Object.MatchesConnection(isRight, senseGloves[i].connectionMethod)) { //This Sense Glove is elligible for a connection and is not already connected. bool succesfullLink = this.senseGloves[i].LinkToGlove(index); if (succesfullLink) { //only when it is actually assigned do we break. SenseGlove_DeviceManager.gloveLinked[index] = true; //we linked the glove at Index. linked = true; break; } } } else { //Warn devs when their SenseGlove_Objects have not been assigned. Debug.LogError("NullRefrence exception occured in " + this.name + ". You likely haven't assigned it via the inspector."); } } if (!linked) { this.OnGloveDetected(glove, index); //only fire event if the glove was not assigned. } } else { Debug.LogWarning("GloveDetected event was fired twice for the same device. Most likely you have two instances of DeviceManager running. " + "We reccommend removing duplicate instances."); } }
public void SetBuzz(int[] levels) { if (CanTestBuzzMotors) { int[] buzzCmd = BuzzMotorLvls; for (int f = 0; f < 5 && f < levels.Length; f++) //ensures it works even if levels is not large enough { buzzCmd[f] = Mathf.Clamp(levels[f], 0, 100); } BuzzMotorLvls = buzzCmd; //updates latest SenseGlove iGlove = (SenseGlove)senseGlove.GetInternalObject(); if (iGlove != null) { iGlove.SendBuzzCmd(buzzCmd); } else { Debug.Log("Could not send Buzz command because we have no Glove"); } } }
//------------------------------------------------------------------------------------------------------------------------------------ // Communication methods. #region Communication /// <summary> /// Extract a SenseGlove matching the parameters of this SenseGlove_Object from a list retieved by the SenseGloveCs.DeviceScanner. /// </summary> /// <param name="devices"></param> /// <returns></returns> private SenseGlove ExtractSenseGlove(SenseGloveCs.IODevice[] devices) { for (int i = 0; i < devices.Length; i++) { if (devices[i] is SenseGlove) { SenseGlove tempGlove = ((SenseGlove)devices[i]); GloveData tempData = tempGlove.GetData(false); //SenseGlove_Debugger.Log("Dataloaded = " + tempData.dataLoaded + ". IsUsed = " + SenseGlove_Manager.IsUsed(tempData.deviceID) + ". isRight = " + tempData.isRight); if (tempData.dataLoaded && !SenseGlove_Manager.IsUsed(tempData.deviceID)) { //the SenseGlove is done loading data AND is not already in memory if ((this.connectionMethod == ConnectionMethod.FindNextGlove) || (this.connectionMethod == ConnectionMethod.FindNextLeftHand && !tempData.isRight) || (this.connectionMethod == ConnectionMethod.FindNextRightHand && tempData.isRight)) { return(tempGlove); } } } } return(null); }
public void SetFFB(int[] levels) { if (CanTestFFB) { int[] FFBcmd = FFBLvls; for (int f = 0; f < 5 && f < levels.Length; f++) //ensures it works even if levels is not large enough { FFBcmd[f] = Mathf.Clamp(levels[f], 0, 100); } FFBLvls = FFBcmd; //updates latest SenseGlove iGlove = (SenseGlove)senseGlove.GetInternalObject(); if (iGlove != null) { iGlove.BrakeCmd(FFBcmd); } else { Debug.Log("Could not send FFB command because we have no Glove"); } } }
// Update is called once per frame void Update() { if (!standBy) { if (this.elapsedTime < SenseGlove_Object.setupTime) { this.elapsedTime += Time.deltaTime; } else if (this.glove == null) //No connection yet... { if (this.connectionMethod == ConnectionMethod.HardCoded) { //no glove was ever assigned... this.RetryConnection(); //keep trying! } else { SenseGlove myGlove = ExtractSenseGlove(SenseGloveCs.DeviceScanner.GetDevices()); if (myGlove != null) //The glove matches our parameters! { this.glove = myGlove; SenseGlove_Manager.SetUsed(this.glove.GetData(false).deviceID, true); this.glove.OnFingerCalibrationFinished += Glove_OnFingerCalibrationFinished; } else { if (this.canReport) { string message = this.gameObject.name + " looking for SenseGlove..."; if (this.connectionMethod == ConnectionMethod.FindNextLeftHand) { message = this.gameObject.name + " looking for left-handed SenseGlove..."; } else if (this.connectionMethod == ConnectionMethod.FindNextRightHand) { message = this.gameObject.name + " looking for right-handed SenseGlove..."; } SenseGlove_Debugger.Log(message); this.canReport = false; } this.elapsedTime = 0; } } } else if (this.connectionMethod == ConnectionMethod.HardCoded && !this.glove.IsConnected()) { //lost connection :( this.canReport = true; this.RetryConnection(); //keep trying! } else if (!gloveReady) { if (this.glove.GetData(false).dataLoaded) { bool runSetup = this.gloveData == null; //used to raise event only once! float[][] oldFingerLengths = null; float[][] oldStartPositions = null; if (this.gloveData != null) { oldFingerLengths = this.GetFingerLengths(); oldStartPositions = SenseGlove_Util.ToPosition(this.GetStartJointPositions()); } this.gloveData = this.glove.GetData(false); //get the latest data without calculating anything. this.rightHand = this.gloveData.isRight; //so that users can use this variable during setup. if (oldFingerLengths != null) { this.SetFingerLengths(oldFingerLengths); } //re-apply old fingerlengths, if possible. if (oldStartPositions != null) { this.SetStartJointPositions(oldStartPositions); } //re=apply joint positions, if possible. this.convertedGloveData = new SenseGlove_Data(this.gloveData, this.glove.communicator.samplesPerSecond, this.glove.TotalCalibrationSteps(), this.glove.TotalCalibrationSteps()); this.SetupWrist(); this.calibratedWrist = false; this.gloveReady = true; if (runSetup) { this.originalLengths = this.gloveData.handModel.GetFingerLengths(); this.originalJoints = this.gloveData.handModel.GetJointPositions(); SenseGlove_Debugger.Log("Sense Glove " + this.convertedGloveData.deviceID + " is ready!"); this.GloveLoaded(); //raise the event! } } } else //glove != null && gloveReady! { this.CheckCalibration(); //Update to the latest GloveData. this.UpdateGloveData(); //Calibrate once more after reconnecting to the glove. if (!calibratedWrist) { this.CalibrateWrist(); this.calibratedWrist = true; } //Update the public values automatically. if (connectionMethod != ConnectionMethod.HardCoded) { this.address = glove.communicator.Address(); } this.rightHand = glove.IsRight(); } } }
static void Main(string[] args) { Console.WriteLine("Testing Sense Glove C# Core Library"); Console.WriteLine("======================================="); if (DeviceList.SenseCommRunning()) //check if the Sense Comm is running. If not, warn the end user. { SenseGlove testGlove; if (SenseGlove.GetSenseGlove(out testGlove)) //retrieves the first Sense Glove it can find. Returns true if one can be found { Console.WriteLine("Activating " + testGlove.ToString() + " on key press."); Console.ReadKey(); //std::this_thread::sleep_for(std::chrono::milliseconds(1000)); //vibrating for for 200ms. testGlove.SendHaptics(new SG_BuzzCmd(0, 80, 0, 0, 0)); //vibrate the index fingerat 80% intensity. System.Threading.Thread.Sleep(1000); testGlove.SendHaptics(SG_BuzzCmd.Off); //turn off all Buzz Motors. System.Threading.Thread.Sleep(10); SG_Model model = testGlove.GetGloveModel(); //Retrieve device information Console.WriteLine(""); Console.WriteLine(model.ToString(true)); //Log some basic information to the user. (true indicates a short notation is desired) //Retrieving Sensor Data (raw). The lowest level data available SG_SensorData sensorData; if (testGlove.GetSensorData(out sensorData)) //if GetSensorData is true, we have sucesfully recieved data { Console.WriteLine(""); Console.WriteLine(sensorData.ToString()); } //Retrieving Glove Pose: The position / rotation of the glove, as well as its sensor angles placed in the right direction. SG_GlovePose glovePose; if (testGlove.GetGlovePose(out glovePose)) { //As an example, lets calculate fingertip positions. //If we wish to calculate hand variables, we need a "hand profile" to tell the Sense Glove our hand lengths. SG_HandProfile handProfile = SG_HandProfile.Default(testGlove.IsRight()); //create a default profile, either left or right. Vect3D[] tipPositions = glovePose.CalculateFingerTips(handProfile); //calculates fingertip position Console.WriteLine(""); Console.WriteLine("Fingertip positions relative to Wrist:"); for (int f = 0; f < tipPositions.Length; f++) { Console.WriteLine(((SGCore.Finger)f).ToString() + ": " + tipPositions[f].ToString()); //writes "thumb: ", "index: " etc. } float dThumbIndex = tipPositions[0].DistTo(tipPositions[1]); //calculates the distance between thumb (0) and index finger (1), in mm. Console.WriteLine("The distance between thumb and index finger is " + dThumbIndex + "mm."); } } else { Console.WriteLine("No sense gloves connected to the system. Ensure the USB connection is secure, then try again."); } } else { Console.WriteLine("SenseComm is not running. Please start it and try again."); } Console.WriteLine("======================================="); Console.WriteLine("Press any key to exit."); Console.ReadKey(); }
/// <summary> Create a new instance of the GloveDetectedArgs. </summary> /// <param name="glove"></param> public GloveDetectedArgs(SenseGlove glove, int gloveIndex) { this.DeviceID = glove.GetData(false).deviceID; this.RightHanded = glove.IsRight(); this.DeviceIndex = gloveIndex; }