I want to get the button inputs of Vive Trackers in this script

Hi group,

My C# skills are a bit limited so here is my question:
I am using the Vive Trackers without the HMD, which works great. I am getting the Position of the Trackers fine with these scripts:
https://github.com/ebadier/ViveTrackers

But I also want to get button input from the Trackers. But I don’t know how to do it

This is what I understand:
In the ViveManager.cs the device is being recognised, and the position is being passed on to the ViveTracker.cs script

using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEngine;
using Valve.VR;
namespace ViveTrackers
{
    /// <summary>
    /// This class is used to manage Vive Tracker devices using OpenVR API.
    /// To run correctly, this class needs SteamVR application to run on the same computer.
    /// 1) To create the trackers, call the RefreshTrackers() method. This method can be called multiple times during runtime.
    /// - You can define a restricted set of Vive Tracker to create during runtime using the config file ViveTrackers.csv.
    /// - Using the config file or not, only the available connected devices in SteamVR are instantiated during runtime.
    /// 2) Once the trackers are created, you can update trackers'transforms using the UpdateTrackers() method.
    /// Example of config file content (# is used to comment):
    /// SerialNumber;Name;
    /// LHR-5850D511;A;
    /// LHR-9F7F5582;B;
    /// #LHR-3CECF391;C;
    /// #LHR-D5918492;D;
    /// #LHR-AC3ABE2E;E;
    /// </summary>
    public sealed class ViveTrackersManager : ViveTrackersManagerBase
    {
        [Tooltip("The path of the file containing the list of the restricted set of trackers to use")]
        public string configFilePath = "ViveTrackers.csv";
        [Tooltip("True, to create only the trackers declared in the config file. False, to create all connected trackers available in SteamVR.")]
        public bool createDeclaredTrackersOnly = false;
        [Tooltip("Log tracker detection or not. Useful to discover trackers' serial numbers")]
        public bool logTrackersDetection = true;
        private bool _ovrInit = false;
        private CVRSystem _cvrSystem = null;
        // Trackers declared in config file [TrackedDevice_SerialNumber, Name]
        private Dictionary<string, string> _declaredTrackers = new Dictionary<string, string>();
        // Poses for all tracked devices in OpenVR (HMDs, controllers, trackers, etc...).
        private TrackedDevicePose_t[] _ovrTrackedDevicePoses = new TrackedDevicePose_t[OpenVR.k_unMaxTrackedDeviceCount];
        private SteamVR_Action_Boolean triggerAction; // The action for the trigger button
        private void Awake()
        {
            if (createDeclaredTrackersOnly)
            {
                if (File.Exists(configFilePath))
                {
                    // Read config file
                    using (StreamReader reader = File.OpenText(configFilePath))
                    {
                        // Read Header
                        string line = reader.ReadLine();
                        char separator = line.Contains(";") ? ';' : ',';
                        // Read Data
                        while ((line = reader.ReadLine()) != null)
                        {
                            // # is used to comment line
                            if (!line.StartsWith("#", System.StringComparison.InvariantCulture))
                            {
                                string[] items = line.Split(separator);
                                _declaredTrackers.Add(items[0], items[1]);
                            }
                        }
                    }
                    Debug.Log("[ViveTrackersManager] " + _declaredTrackers.Count + " trackers declared in config file : " + configFilePath);
                }
                else
                {
                    Debug.LogWarning("[ViveTrackersManager] config file not found : " + configFilePath + " !");
                }
            }
        }
        /// <summary>
        /// Update ViveTracker transforms using the corresponding Vive Tracker devices.
        /// </summary>
        public override void UpdateTrackers(float pDeltaTime)
        {
            if (!_ovrInit)
            {
                return;
            }
            // Fetch last Vive Tracker devices poses.
            _cvrSystem.GetDeviceToAbsoluteTrackingPose(ETrackingUniverseOrigin.TrackingUniverseStanding, 0, _ovrTrackedDevicePoses);
            // Apply poses to ViveTracker objects.
            foreach (var tracker in _trackers)
            {
                TrackedDevicePose_t pose = _ovrTrackedDevicePoses[tracker.ID.trackedDevice_Index];
                SteamVR_Utils.RigidTransform rigidTransform = new SteamVR_Utils.RigidTransform(pose.mDeviceToAbsoluteTracking);
                tracker.UpdateState(pose.bDeviceIsConnected, pose.bPoseIsValid, (pose.eTrackingResult == ETrackingResult.Running_OK), 
                    rigidTransform.pos, rigidTransform.rot, pDeltaTime);
            }
        }
        /// <summary>
        /// Scan for available Vive Tracker devices and creates ViveTracker objects accordingly.
        /// Init OpenVR if not already done.
        /// </summary>
        public override void RefreshTrackers()
        {
            // Delete existing ViveTrackers
            foreach (ViveTracker tracker in _trackers)
            {
                Destroy(tracker.gameObject);
            }
            _trackers.Clear();
            // OVR check
            if (!_ovrInit)
            {
                _ovrInit = _InitOpenVR();
                if (!_ovrInit)
                {
                    return;
                }
            }
            Debug.Log("[ViveTrackersManager] Scanning for Tracker devices...");
            for (uint i = 0; i < OpenVR.k_unMaxTrackedDeviceCount; ++i)
            {
                ETrackedDeviceClass deviceClass = _cvrSystem.GetTrackedDeviceClass(i);
                if (deviceClass == ETrackedDeviceClass.GenericTracker)
                {
                    string sn = _GetTrackerSerialNumber(i);
                    if (logTrackersDetection)
                    {
                        Debug.Log("[ViveTrackersManager] Tracker detected : " + sn);
                    }
                    if (sn != "")
                    {
                        string trackerName = "";
                        bool declared = _declaredTrackers.TryGetValue(sn, out trackerName);
                        // Creates only trackers declared in config file or all (if !createDeclaredTrackersOnly).
                        if (declared || !createDeclaredTrackersOnly)
                        {
                            ViveTracker vt = GameObject.Instantiate<ViveTracker>(prefab, origin.transform.position, origin.transform.rotation, origin.transform);
                            vt.Init(new ViveTrackerID(i, sn), declared ? trackerName : sn);
                            _trackers.Add(vt);
                        }
                    }
                }
            }
            // Check
            if (_trackers.Count == 0)
            {
                Debug.LogWarning("[ViveTrackersManager] No trackers available !");
                return;
            }
            // Sort Trackers by name.
            _trackers.Sort((ViveTracker x, ViveTracker y) => { return string.Compare(x.name, y.name); });
            Debug.Log(string.Format("[ViveTrackersManager] {0} trackers declared and {1} trackers available:", _declaredTrackers.Count, _trackers.Count));
            foreach (ViveTracker tracker in _trackers)
            {
                Debug.Log(string.Format("[ViveTrackersManager] -> Tracker : Name = {0} ; SN = {1} ; Index = {2}", tracker.name, tracker.ID.trackedDevice_SerialNumber, tracker.ID.trackedDevice_Index));
            }
            // Fire Action.
            if (TrackersFound != null)
            {
                TrackersFound(_trackers);
            }
        }
        private bool _InitOpenVR()
        {
            // OpenVR Init
            EVRInitError error = EVRInitError.None;
            _cvrSystem = OpenVR.Init(ref error, EVRApplicationType.VRApplication_Other);
            if (error != EVRInitError.None)
            {
                Debug.LogError("[ViveTrackersManager] OpenVR Error : " + error);
                return false;
            }
            Debug.Log("[ViveTrackersManager] OpenVR initialized.");
            return true;
        }
        private string _GetTrackerSerialNumber(uint pTrackerIndex)
        {
            string sn = "";
            ETrackedPropertyError error = new ETrackedPropertyError();
            StringBuilder sb = new StringBuilder();
            _cvrSystem.GetStringTrackedDeviceProperty(pTrackerIndex, ETrackedDeviceProperty.Prop_SerialNumber_String, sb, OpenVR.k_unMaxPropertyStringSize, ref error);
            if (error == ETrackedPropertyError.TrackedProp_Success)
            {
                sn = sb.ToString();
            }
            return sn;
        }
    }
}

The relevant method is:

        public override void UpdateTrackers(float pDeltaTime)
        {
            if (!_ovrInit)
            {
                return;
            }
            // Fetch last Vive Tracker devices poses.
            _cvrSystem.GetDeviceToAbsoluteTrackingPose(ETrackingUniverseOrigin.TrackingUniverseStanding, 0, _ovrTrackedDevicePoses);
            // Apply poses to ViveTracker objects.
            foreach (var tracker in _trackers)
            {
                TrackedDevicePose_t pose = _ovrTrackedDevicePoses[tracker.ID.trackedDevice_Index];
                SteamVR_Utils.RigidTransform rigidTransform = new SteamVR_Utils.RigidTransform(pose.mDeviceToAbsoluteTracking);
                tracker.UpdateState(pose.bDeviceIsConnected, pose.bPoseIsValid, (pose.eTrackingResult == ETrackingResult.Running_OK),
                    rigidTransform.pos, rigidTransform.rot, pDeltaTime);
            }
        }

In the ViveManager.cs I would also want to pass on the button states of the trackers. :

  • I don’t know how to get the button state in this context
  • I don’t know how to pass that information on to the ViveTracker.cs script

In the ViveTracker.cs the Position and Rotation are updated with this method:

        public void UpdateState(bool pIsConnected, bool pIsPoseValid, bool pIsOpticallyTracked, Vector3 pLocalPosition, Quaternion pLocalRotation, float pDeltaTime)
        {
            bool isPosValid, isRotValid;
            _trackingStateWatcher.Update(out isPosValid, out isRotValid, pIsConnected, pIsPoseValid, pIsOpticallyTracked, pDeltaTime, imuOnlyReliablePositionDuration);
            //Debug.Log(string.Format("{0} | Connected : {1} | PoseValid : {2} | OpticalTracking : {3} | PosOK : {4} | RotOK : {5}",
            //    name, pIsConnected, pIsPoseValid, pIsOpticallyTracked, isPosValid, isRotValid));

            // Warn for states changed.
            Connected = pIsConnected;
            PositionValid = isPosValid;
            RotationValid = isRotValid;

            // Update only if the tracker is reliably tracked.
            // This way, the tracker keeps its last transform when the tracking is lost (better than using unreliable values).
            // POSITION
            if (isPosValid)
            {
                _transform.localPosition = pLocalPosition;
            }
            // ROTATION
            if (isRotValid)
            {
                if (_calibrate)
                {
                    _trackerRotationOffset = Quaternion.Inverse(pLocalRotation);
                    _calibrate = false;

                    if (Calibrated != null)
                    {
                        Calibrated(this);
                    }
                }
                _transform.localRotation = pLocalRotation * _trackerRotationOffset;
            }
        }

Help would be appreciated!

Answering my own question here:
Buttons are now implemented in the script:
https://github.com/ebadier/ViveTrackers

Thanks to the great work of ebadier