/** * @file * * @author Max Lammers * @author Mamadou Babaei * * @section LICENSE * * Copyright (c) 2020 - 2023 SenseGlove * * @section DESCRIPTION * * An interface for any of our gloves that can track hand motion and/or send * force / vibrotactile feedback. */ #pragma once #include #include #include #include "Platform.hpp" #include "SGDevice.hpp" #include "Tracking.hpp" namespace SGCore { namespace Haptics { class BuzzCommand; class ForceFeedbackCommand; class ThumperCommand; };// namespace Haptics namespace Kinematics { class BasicHandModel; class Quat; class Vect3D; };// namespace Kinematics class HandPose; class HandProfile; /// A glove developed by SenseGlove, that has hand tracking and/or haptic feedback functionality. class SGCORE_API HapticGlove; };// namespace SGCore /// A glove developed by SenseGlove, that has hand tracking and/or haptic feedback functionality. class SGCORE_API SGCore::HapticGlove : public SGDevice { public: //-------------------------------------------------------------------------------------- // Device Detection / enumeration /// Get all Haptic Gloves detected on this system.. /// static std::vector> GetHapticGloves(); /// Get the first Haptic Glove detected on this system. /// /// static bool GetGlove(std::shared_ptr& out_glove); /// Get the first left/right Haptic Glove detected on this system. /// /// static bool GetGlove(bool bRightHanded, std::shared_ptr& out_glove); private: struct Impl; std::unique_ptr Pimpl; public: /// The basic constructor. HapticGlove(); /** * The copy constructor. */ HapticGlove(const HapticGlove& rhs); /** * The move constructor. */ HapticGlove(HapticGlove&& rhs) noexcept; /// The basic destructor. virtual ~HapticGlove() override; public: /** * The copy assignment operator. */ HapticGlove& operator=(const HapticGlove& rhs); /** * The move assignment operator. */ HapticGlove& operator=(HapticGlove&& rhs) noexcept; protected: //-------------------------------------------------------------------------------------- // Properties /// The last Force-Feedback command sent by this glove. SG_NODISCARD const Haptics::ForceFeedbackCommand& GetLastForceFeedbackCommand() const; void SetLastForceFeedbackCommand(const Haptics::ForceFeedbackCommand& command); /// The Vibromotor command sent by this glove. SG_NODISCARD const Haptics::BuzzCommand& GetLastBuzzCommand() const; void SetLastBuzzCommand(const Haptics::BuzzCommand& command); /// The thumper command sent by this glove. SG_NODISCARD const Haptics::ThumperCommand& GetLastThumperCommand() const; void SetLastThumperCommand(const Haptics::ThumperCommand& command); /// The minimum calibration values measured by this glove. SG_NODISCARD const std::vector& GetMinValues() const; void SetMinValues(const std::vector& values); /// The maximum calibration values measured by this glove. SG_NODISCARD const std::vector& GetMaxValues() const; void SetMaxValues(const std::vector& values); public: //-------------------------------------------------------------------------------------- // SGDevice Methods /// Get the DeviceType enumerator of this device; used to check if its a SenseGlove/Nova/etc. SG_NODISCARD virtual EDeviceType GetDeviceType() const override; /// Retrieve this glove's unique identifier. SG_NODISCARD virtual std::string GetDeviceId() const override; /// Retrieve this glove's hardware (sub) version. "DK1", "DK2", etc. SG_NODISCARD virtual std::string GetHardwareVersion() const override; /// Retrieve this device's main firmware version. v4.12 returns 4. SG_NODISCARD virtual int32_t GetFirmwareVersion() const override; /// Retrieve this device's sub firmware version. v4.12 returns 12. SG_NODISCARD virtual int32_t GetSubFirmwareVersion() const override; public: //-------------------------------------------------------------------------------------- // Tracking Methods /// Returns true if this glove is made for a right hand. If false, it's a left hand. /// SG_NODISCARD virtual bool IsRight() const #if ! SENSEGLOVE_UNREAL_ENGINE_PLUGIN = 0 #endif /* ! SENSEGLOVE_UNREAL_ENGINE_PLUGIN */ ; /// Retrieve this glove's IMU rotation, if if has any. /// /// virtual bool GetImuRotation(Kinematics::Quat& out_imu); /// Calculate the Hand Pose of this device, provided it has Hand Tracking available /// /// /// virtual bool GetHandPose(const Kinematics::BasicHandModel& handGeometry, const HandProfile& handProfile, HandPose& out_handPose); /// Calculate the HandPose of this Device, taking into account user values, but not hand geometry. /// /// /// virtual bool GetHandPose(const HandProfile& handProfile, HandPose& out_handPose); /// Retrieve a HandPose based on the latest profile, but with a specific hand geometry. /// /// /// virtual bool GetHandPose(const Kinematics::BasicHandModel& handGeometry, HandPose& out_handPose); /// Retrieve a HandPose based on the latest profile and default hand Geometry. /// /// /// virtual bool GetHandPose(HandPose& out_handPose); #if SG_PLATFORM_ANDROID virtual bool GetHandPose(float deltaTime, HandPose& out_handPose); #endif /* SG_PLATFORM_ANDROID */ public: //-------------------------------------------------------------------------------------- // Haptics Methods. /// Stops all Haptic effects if any are currently playing. Useful at the end of simulations or when resetting. virtual void StopHaptics(); virtual void StopVibrations(); //other -generic- force-feedback methods (?) /// Send Haptic Commands to this Glove. /// virtual void SendHaptics(const Haptics::ForceFeedbackCommand& forceFeedbackCommand); /// Send Haptic Commands to this Glove. /// virtual void SendHaptics(const Haptics::BuzzCommand& buzzCommand); /// Send Haptic Commands to this Glove. /// virtual void SendHaptics(const Haptics::ThumperCommand& thumperCommand); /// Send Haptic Commands to this Glove. /// /// virtual void SendHaptics(const Haptics::ForceFeedbackCommand& forceFeedbackCommand, const Haptics::BuzzCommand& buzzCommand); /// Send Haptic Commands to this Glove. /// /// /// virtual void SendHaptics(const Haptics::ForceFeedbackCommand& forceFeedbackCommand, const Haptics::BuzzCommand& buzzCommand, const Haptics::ThumperCommand& thumperCommand); public: //-------------------------------------------------------------------------------------- // Calibration Methods #if SG_PLATFORM_ANDROID void StartCalibration(); #endif /* SG_PLATFORM_ANDROID */ /// Retrieve calibration values of this glove, as an array of size 5, containing x (roll), y (flexion), z (abduction) values. virtual bool GetCalibrationValues(std::vector& out_values); /// Reset Calibration range for this Device. virtual void ResetCalibrationRange(); /// Updates calibration values only. virtual void UpdateCalibrationRange(); /// Updates calibration values only. virtual void UpdateCalibrationRange(const std::vector& calibrationValues); /// Access the minimum- and maximum sensor values measured by this Haptic Glove, in this session. /// /// virtual void GetCalibrationRange(std::vector& out_minValues, std::vector& out_maxValues); /// Updates Calibration values and applies it to the Profile. /// virtual void UpdateCalibration(HandProfile& out_profile); /// Apply this glove's calibration range to a handProfile. /// virtual void ApplyCalibration(HandProfile& out_profile) const; public: //-------------------------------------------------------------------------------------- // 6DoF Position Tracking /// Retrieve the location of the wrist, based on a reference location and default glove-hand offsets. /// The simplest interface, using default offsets. /// Position of the tracked object, in mm, relative to your origin /// Rotation of the tracked object relative to your origin /// The hardware mounted on the SenseGlove. /// The 3D Position of the wrist, in mm, relative to your origin /// The 3D Rotation of the wrist, relative to your origin virtual void GetWristLocation(const Kinematics::Vect3D& referencePosition, const Kinematics::Quat& referenceRotation, EPositionalTrackingHardware trackingHardware, Kinematics::Vect3D& out_wristPosition, Kinematics::Quat& out_wristRotation) const; /// Retrieve the location of the glove origin, based on a reference location. /// Position of the tracked object, in mm, relative to your origin /// Rotation of the tracked object relative to your origin /// The hardware mounted on the SenseGlove. /// The 3D Position of the glove, in mm, relative to your origin /// The 3D Rotation of the glove, relative to your origin virtual void GetGloveLocation(const Kinematics::Vect3D& referencePosition, const Kinematics::Quat& referenceRotation, EPositionalTrackingHardware trackingHardware, Kinematics::Vect3D& out_glovePosition, Kinematics::Quat& out_gloveRotation) const; };