فهرست منبع

1.添加一个手柄6轴功能

slambb 1 سال پیش
والد
کامیت
051feb46c7

+ 80 - 0
Assets/Demo/Materials/Green.mat

@@ -0,0 +1,80 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!21 &2100000
+Material:
+  serializedVersion: 8
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_Name: Green
+  m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
+  m_ValidKeywords: []
+  m_InvalidKeywords: []
+  m_LightmapFlags: 4
+  m_EnableInstancingVariants: 0
+  m_DoubleSidedGI: 0
+  m_CustomRenderQueue: -1
+  stringTagMap: {}
+  disabledShaderPasses: []
+  m_SavedProperties:
+    serializedVersion: 3
+    m_TexEnvs:
+    - _BumpMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailAlbedoMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailMask:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailNormalMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _EmissionMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _MainTex:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _MetallicGlossMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _OcclusionMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _ParallaxMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    m_Ints: []
+    m_Floats:
+    - _BumpScale: 1
+    - _Cutoff: 0.5
+    - _DetailNormalMapScale: 1
+    - _DstBlend: 0
+    - _GlossMapScale: 1
+    - _Glossiness: 0.5
+    - _GlossyReflections: 1
+    - _Metallic: 0
+    - _Mode: 0
+    - _OcclusionStrength: 1
+    - _Parallax: 0.02
+    - _SmoothnessTextureChannel: 0
+    - _SpecularHighlights: 1
+    - _SrcBlend: 1
+    - _UVSec: 0
+    - _ZWrite: 1
+    m_Colors:
+    - _Color: {r: 0, g: 1, b: 0.1422956, a: 1}
+    - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
+  m_BuildTextureStacks: []

+ 8 - 0
Assets/Demo/Materials/Green.mat.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 05a5df598cd0b4d4c93487a330e26153
+NativeFormatImporter:
+  externalObjects: {}
+  mainObjectFileID: 2100000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 80 - 0
Assets/Demo/Materials/Red.mat

@@ -0,0 +1,80 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!21 &2100000
+Material:
+  serializedVersion: 8
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_Name: Red
+  m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
+  m_ValidKeywords: []
+  m_InvalidKeywords: []
+  m_LightmapFlags: 4
+  m_EnableInstancingVariants: 0
+  m_DoubleSidedGI: 0
+  m_CustomRenderQueue: -1
+  stringTagMap: {}
+  disabledShaderPasses: []
+  m_SavedProperties:
+    serializedVersion: 3
+    m_TexEnvs:
+    - _BumpMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailAlbedoMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailMask:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailNormalMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _EmissionMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _MainTex:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _MetallicGlossMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _OcclusionMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _ParallaxMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    m_Ints: []
+    m_Floats:
+    - _BumpScale: 1
+    - _Cutoff: 0.5
+    - _DetailNormalMapScale: 1
+    - _DstBlend: 0
+    - _GlossMapScale: 1
+    - _Glossiness: 0.5
+    - _GlossyReflections: 1
+    - _Metallic: 0
+    - _Mode: 0
+    - _OcclusionStrength: 1
+    - _Parallax: 0.02
+    - _SmoothnessTextureChannel: 0
+    - _SpecularHighlights: 1
+    - _SrcBlend: 1
+    - _UVSec: 0
+    - _ZWrite: 1
+    m_Colors:
+    - _Color: {r: 1, g: 0.00989685, b: 0, a: 1}
+    - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
+  m_BuildTextureStacks: []

+ 8 - 0
Assets/Demo/Materials/Red.mat.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: b31959c9aa560174881f2c68dd843d5b
+NativeFormatImporter:
+  externalObjects: {}
+  mainObjectFileID: 2100000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 738 - 141
Assets/InfraredDemo/Scenes/InfraredDemo.unity


+ 116 - 14
Assets/InfraredDemo/Scripts/InfraredDemo.cs

@@ -35,6 +35,7 @@ public class InfraredDemo : MonoBehaviour
     void Update()
     {
         UpdateBluetoothModule();
+        UpdateBluetoothModule6Axis();
         UpdateInfraredCamera();
     }
 
@@ -395,37 +396,71 @@ public class InfraredDemo : MonoBehaviour
     [SerializeField] Button _btnConnect;
     [SerializeField] Text _textMacAddress;
     [SerializeField] Text _textBattery;
+    SmartBowHelper OriginSmartBowHelper;
+
+    //六轴部分按钮操作
+    [SerializeField] Button _btnConnect6Axis;
+    [SerializeField] Text _textMacAddress6Axis;
+    [SerializeField] Text _textBattery6Axis;
+    SmartBowHelper BGBoxSmartBowHelper;
+    [SerializeField] GameObject _BGBoxObj;
+
     void InitBluetoothModule()
     {
-        SmartBowHelper.GetInstance().OnBluetoothModuleInited += OnBluetoothModuleInited;
-        SmartBowHelper.GetInstance().OnBluetoothError += OnBluetoothError;
-        SmartBowHelper.GetInstance().OnShooting += OnShooting;
+        SmartBowLogger.isDebug = true;
+
+        OriginSmartBowHelper = SmartBowHelper.NewInstance();
+        OriginSmartBowHelper.OnBluetoothModuleInited += OnBluetoothModuleInited;
+        OriginSmartBowHelper.OnBluetoothError += OnBluetoothError;
+        OriginSmartBowHelper.OnShooting += OnShooting;
         _btnConnect.onClick.AddListener(OnClick_Connect);
+     
+
+
+        //6轴部分代码
+        BGBoxSmartBowHelper = SmartBowHelper.NewInstance();
+        BGBoxSmartBowHelper.OnBluetoothModuleInited += OnBluetoothModuleInited6Axis;
+        BGBoxSmartBowHelper.OnBluetoothError += OnBluetoothError6Axis;
+        BGBoxSmartBowHelper.OnSixAxisRotationUpdate += (eulerAngles) =>
+        {
+            _BGBoxObj.transform.eulerAngles = eulerAngles;
+        };
+        //识别当前手柄
+        BGBoxSmartBowHelper.SetFilters("BGBox_202012");
+        //设置手柄解析
+        BGBoxSmartBowHelper.SetSensorAxisType(SensorAxisType.SixAxisSensor);
+        _btnConnect6Axis.onClick.AddListener(OnClick_ConnectBGBox);
+
+        if (BluetoothWindows.IsWindows()) {
+            BleWinHelper.RegisterTo(OriginSmartBowHelper.gameObject, OriginSmartBowHelper.CreateBluetoothWindows());
+            BleWinHelper.RegisterTo(BGBoxSmartBowHelper.gameObject, BGBoxSmartBowHelper.CreateBluetoothWindows());
+        }
+        //Debug.Log("InitBluetoothModule");
     }
     void UpdateBluetoothModule()
     {
         //更新显示蓝牙状态
-        BluetoothStatusEnum bluetoothStatus = SmartBowHelper.GetInstance().GetBluetoothStatus();
+        BluetoothStatusEnum bluetoothStatus = OriginSmartBowHelper.GetBluetoothStatus();
         Text btnConnectText = _btnConnect.GetComponentInChildren<Text>();
         if (bluetoothStatus == BluetoothStatusEnum.None) btnConnectText.text = "<color=blue>未连接</color>(点击连接)";
         if (bluetoothStatus == BluetoothStatusEnum.Connecting) btnConnectText.text = "<color=#FF670D>连接中</color>";
         if (bluetoothStatus == BluetoothStatusEnum.Connected)
         {
-            if (SmartBowHelper.GetInstance().IsBluetoothModuleInited()) btnConnectText.text = "<color=green>已连接</color>(点击断开)";
+            if (OriginSmartBowHelper.IsBluetoothModuleInited()) btnConnectText.text = "<color=green>已连接</color>(点击断开)";
             else btnConnectText.text = "<color=green>已连接</color><color=blue>(正在初始化)</color>";
         }
         //更新显示电量
-        int battery = SmartBowHelper.GetInstance().GetBattery();
+        int battery = OriginSmartBowHelper.GetBattery();
         _textBattery.text = battery > 0 ? $"电量值:{battery}" : "未获得电量值";
         //更新显示Mac地址
-        string macAddress = SmartBowHelper.GetInstance().GetMacAddress();
+        string macAddress = OriginSmartBowHelper.GetMacAddress();
         _textMacAddress.text = macAddress != null ? $"Mac地址:{macAddress}" : "未获得Mac地址";
     }
     void OnBluetoothModuleInited()
     {
 
-        SmartBowHelper.GetInstance().StartRotationSensor();
-        SmartBowHelper.GetInstance().StartShootingSensor();
+        OriginSmartBowHelper.StartRotationSensor();
+        OriginSmartBowHelper.StartShootingSensor();
     }
     void OnBluetoothError(BluetoothError error, string message)
     {
@@ -443,18 +478,85 @@ public class InfraredDemo : MonoBehaviour
     }
     void OnClick_Connect()
     {
-        if (SmartBowHelper.GetInstance().GetBluetoothStatus() == BluetoothStatusEnum.Connecting) return;
-        if (SmartBowHelper.GetInstance().GetBluetoothStatus() == BluetoothStatusEnum.None)
+        if (OriginSmartBowHelper.GetBluetoothStatus() == BluetoothStatusEnum.Connecting) return;
+        if (OriginSmartBowHelper.GetBluetoothStatus() == BluetoothStatusEnum.None)
         {
-            SmartBowHelper.GetInstance().Connect("test", 1);
+            OriginSmartBowHelper.Connect("test", 1);
             return;
         }
-        if (SmartBowHelper.GetInstance().GetBluetoothStatus() == BluetoothStatusEnum.Connected)
+        if (OriginSmartBowHelper.GetBluetoothStatus() == BluetoothStatusEnum.Connected)
         {
-            SmartBowHelper.GetInstance().Disconnect();
+            OriginSmartBowHelper.Disconnect();
             return;
         }
     }
+
+
+    /// <summary>
+    /// 更新BGBox信息
+    /// </summary>
+    void UpdateBluetoothModule6Axis()
+    {
+        //更新显示蓝牙状态
+        BluetoothStatusEnum bluetoothStatus = BGBoxSmartBowHelper.GetBluetoothStatus();
+        Text btnConnectText = _btnConnect6Axis.GetComponentInChildren<Text>();
+        if (bluetoothStatus == BluetoothStatusEnum.None) btnConnectText.text = "<color=blue>未连接</color>(点击连接)";
+        if (bluetoothStatus == BluetoothStatusEnum.Connecting) btnConnectText.text = "<color=#FF670D>连接中</color>";
+        if (bluetoothStatus == BluetoothStatusEnum.Connected)
+        {
+            if (BGBoxSmartBowHelper.IsBluetoothModuleInited()) btnConnectText.text = "<color=green>已连接</color>(点击断开)";
+            else btnConnectText.text = "<color=green>已连接</color><color=blue>(正在初始化)</color>";
+        }
+        //更新显示电量
+        int battery = BGBoxSmartBowHelper.GetBattery();
+        _textBattery6Axis.text = battery > 0 ? $"电量值:{battery}" : "未获得电量值";
+        //更新显示Mac地址
+        string macAddress = BGBoxSmartBowHelper.GetMacAddress();
+        _textMacAddress6Axis.text = macAddress != null ? $"Mac地址:{macAddress}" : "未获得Mac地址";
+    }
+    void OnBluetoothModuleInited6Axis()
+    {
+        BGBoxSmartBowHelper.StartRotationSensor();
+    }
+    public void Open6Axis()
+    {
+        BGBoxSmartBowHelper.StartRotationSensor();
+    }
+    public void Close6Axis() {
+        BGBoxSmartBowHelper.StopRotationSensor();
+    }
+
+    public void Reset6Axis()
+    {
+        // if(sixAxisFusion!=null) sixAxisFusion.ResetToInitialRotation();
+        BGBoxSmartBowHelper.ResetSixAxisIdentity();
+    }
+
+    void OnBluetoothError6Axis(BluetoothError error, string message)
+    {
+        Debug.Log("6Axis OnBluetoothError:" + error);
+        if (error == BluetoothError.ScanNotFoundTargetDevice)
+        {
+            TipText.Show("连接失败,未发现目标设备!");
+            return;
+        }
+        TipText.Show(message);
+    }
+    void OnClick_ConnectBGBox() {
+        if (BGBoxSmartBowHelper.GetBluetoothStatus() == BluetoothStatusEnum.Connecting) return;
+        if (BGBoxSmartBowHelper.GetBluetoothStatus() == BluetoothStatusEnum.None)
+        {
+            BGBoxSmartBowHelper.Connect("test2", 1);
+            return;
+        }
+        if (BGBoxSmartBowHelper.GetBluetoothStatus() == BluetoothStatusEnum.Connected)
+        {
+            BGBoxSmartBowHelper.Disconnect();
+            return;
+        }
+    }
+
+
     #endregion
 }
 public class ParamFloatValue

+ 8 - 0
Assets/SmartBowSDK/Box.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 88276bee6a8d21c48828846bb9923e91
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

BIN
Assets/SmartBowSDK/Box/xbox.fbx


+ 107 - 0
Assets/SmartBowSDK/Box/xbox.fbx.meta

@@ -0,0 +1,107 @@
+fileFormatVersion: 2
+guid: c8d330ee685b9044cae7fef3a005b450
+ModelImporter:
+  serializedVersion: 21300
+  internalIDToNameTable: []
+  externalObjects: {}
+  materials:
+    materialImportMode: 2
+    materialName: 0
+    materialSearch: 1
+    materialLocation: 1
+  animations:
+    legacyGenerateAnimations: 4
+    bakeSimulation: 0
+    resampleCurves: 1
+    optimizeGameObjects: 0
+    removeConstantScaleCurves: 1
+    motionNodeName: 
+    rigImportErrors: 
+    rigImportWarnings: 
+    animationImportErrors: 
+    animationImportWarnings: 
+    animationRetargetingWarnings: 
+    animationDoRetargetingWarnings: 0
+    importAnimatedCustomProperties: 0
+    importConstraints: 0
+    animationCompression: 1
+    animationRotationError: 0.5
+    animationPositionError: 0.5
+    animationScaleError: 0.5
+    animationWrapMode: 0
+    extraExposedTransformPaths: []
+    extraUserProperties: []
+    clipAnimations: []
+    isReadable: 0
+  meshes:
+    lODScreenPercentages: []
+    globalScale: 1
+    meshCompression: 0
+    addColliders: 0
+    useSRGBMaterialColor: 1
+    sortHierarchyByName: 1
+    importVisibility: 1
+    importBlendShapes: 1
+    importCameras: 1
+    importLights: 1
+    nodeNameCollisionStrategy: 1
+    fileIdsGeneration: 2
+    swapUVChannels: 0
+    generateSecondaryUV: 0
+    useFileUnits: 1
+    keepQuads: 0
+    weldVertices: 1
+    bakeAxisConversion: 0
+    preserveHierarchy: 0
+    skinWeightsMode: 0
+    maxBonesPerVertex: 4
+    minBoneWeight: 0.001
+    optimizeBones: 1
+    meshOptimizationFlags: -1
+    indexFormat: 0
+    secondaryUVAngleDistortion: 8
+    secondaryUVAreaDistortion: 15.000001
+    secondaryUVHardAngle: 88
+    secondaryUVMarginMethod: 1
+    secondaryUVMinLightmapResolution: 40
+    secondaryUVMinObjectScale: 1
+    secondaryUVPackMargin: 4
+    useFileScale: 1
+    strictVertexDataChecks: 0
+  tangentSpace:
+    normalSmoothAngle: 60
+    normalImportMode: 0
+    tangentImportMode: 3
+    normalCalculationMode: 4
+    legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0
+    blendShapeNormalImportMode: 1
+    normalSmoothingSource: 0
+  referencedClips: []
+  importAnimation: 1
+  humanDescription:
+    serializedVersion: 3
+    human: []
+    skeleton: []
+    armTwist: 0.5
+    foreArmTwist: 0.5
+    upperLegTwist: 0.5
+    legTwist: 0.5
+    armStretch: 0.05
+    legStretch: 0.05
+    feetSpacing: 0
+    globalScale: 1
+    rootMotionBoneName: 
+    hasTranslationDoF: 0
+    hasExtraRoot: 0
+    skeletonHasParents: 1
+  lastHumanDescriptionAvatarSource: {instanceID: 0}
+  autoGenerateAvatarMappingIfUnspecified: 1
+  animationType: 2
+  humanoidOversampling: 1
+  avatarSetup: 0
+  addHumanoidExtraRootOnlyWhenUsingAvatar: 1
+  remapMaterialsIfMaterialImportModeIsNone: 0
+  additionalBone: 0
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

BIN
Assets/SmartBowSDK/SmartBowSDK.dll


+ 4 - 1
Assets/SmartBowSDK/win/BleWinHelper.cs

@@ -27,7 +27,9 @@ namespace SmartBowSDK
             Debug.Log(LogTag + text);
         }
 
-        private string targetDeviceName = "Bbow_20210501 | HOUYI Pro | Pistol | Pistol M9";
+        private string targetDeviceName = "Bbow_20210501 | ARTEMIS Pro | HOUYI Pro | Pistol | Pistol M9 | BGBox_202012";
+        private string targetDeviceNameHOUYIPro = "HOUYI Pro";
+        private string targetDeviceNameGun = "Pistol | Pistol M9 | Bbow_20210501";
         private string targetService = "{0000fff0-0000-1000-8000-00805f9b34fb}";
         private string targetCharacteristicsNotify = "{0000fff1-0000-1000-8000-00805f9b34fb}";
         private string targetCharacteristicsWrite = "{0000fff2-0000-1000-8000-00805f9b34fb}";
@@ -148,6 +150,7 @@ namespace SmartBowSDK
                             selectedDeviceId = res.id;
                             StopDeviceScan();
                         }
+
                     }
                     else if (status == BleApi.ScanStatus.FINISHED)
                     {

+ 177 - 7
SmartBowSDK/SmartBowSDK/BluetoothAim_SDK.cs

@@ -23,11 +23,24 @@ namespace SmartBowSDK
 
         private BluetoothWindows _bluetoothWindows;
 
+        /// <summary>
+        /// 6轴
+        /// </summary>
+        private o06DOF.SixAxisFusion sixAxisFusion;
+
         /// <summary>
         /// 过滤名称
         /// </summary>
         public string filters { get; set; } = "";
 
+
+        /// <summary>
+        /// 当前的传感器类型
+        /// </summary>
+        public SensorAxisType sensorAxisType { get; set; } = SensorAxisType.NineAxisSensor;
+
+
+
         private void SetStatus(BluetoothStatusEnum newStatus)
         {
             BluetoothStatusEnum oldStatus = bluetoothStatus;
@@ -84,6 +97,16 @@ namespace SmartBowSDK
                 {
                     _bluetoothWindows.Connect();
                     SetStatus(BluetoothStatusEnum.Connecting);
+
+                    //初始化一次六轴解析
+                    if (sixAxisFusion == null)
+                    {
+                        Vector3 accelOffset = Vector3.zero;
+                        Vector3 gyroOffset = Vector3.zero;
+                        float gForce = 1.0f;
+                        float gyroToDegree = 1.0f;
+                        sixAxisFusion = new o06DOF.SixAxisFusion(accelOffset, gyroOffset, gForce, gyroToDegree);
+                    }
                 }
                 return;
             }
@@ -120,7 +143,26 @@ namespace SmartBowSDK
                 _bluetoothHelper = BluetoothHelper.GetNewInstance();
                 _bluetoothHelper.OnConnected += OnConnected;
                 _bluetoothHelper.OnConnectionFailed += OnConnectionFailed;
-                _bluetoothHelper.OnCharacteristicChanged += OnCharacteristicChanged;
+
+                SmartBowLogger.Log(this,"创建蓝牙的SensorAxisType类型:"+ sensorAxisType);
+                if (sensorAxisType == SensorAxisType.SixAxisSensor)
+                {
+                    //6轴时候,另外的解析操作
+                    _bluetoothHelper.OnCharacteristicChanged += OnCharacteristicChanged6Axis;
+                    //初始化一次六轴解析
+                    if (sixAxisFusion == null) {
+                        Vector3 accelOffset = Vector3.zero;
+                        Vector3 gyroOffset = Vector3.zero;
+                        float gForce = 1.0f;
+                        float gyroToDegree = 1.0f;
+                        sixAxisFusion = new o06DOF.SixAxisFusion(accelOffset, gyroOffset, gForce, gyroToDegree);
+                    }
+                }
+                else {
+                    //九轴的解析
+                    _bluetoothHelper.OnCharacteristicChanged += OnCharacteristicChanged;
+                }
+
                 _bluetoothHelper.OnScanEnded += OnScanEnded;
                 _bluetoothHelper.ScanNearbyDevices();
                 _NoneToConnectingStep = 2;
@@ -183,12 +225,32 @@ namespace SmartBowSDK
                     }
                 }
             }
-            StartCoroutine(InitWhenConnected());
+            //指令区分
+            if (sensorAxisType == SensorAxisType.SixAxisSensor)
+            {
+                //6轴指令
+                StartCoroutine(InitWhenConnected6Axis());
+            }
+            else
+            {
+                //九轴
+                StartCoroutine(InitWhenConnected());
+            }
         }
         void OnConnected_windows()
         {
             SetStatus(BluetoothStatusEnum.Connected);
-            StartCoroutine(InitWhenConnected());
+
+            if (sensorAxisType == SensorAxisType.SixAxisSensor)
+            {
+                //6轴指令
+                StartCoroutine(InitWhenConnected6Axis());
+            }
+            else
+            {
+                //九轴
+                StartCoroutine(InitWhenConnected());
+            }
         }
 
         void OnConnectionFailed(BluetoothHelper helper)
@@ -200,7 +262,12 @@ namespace SmartBowSDK
         {
             SetStatus(BluetoothStatusEnum.None);
         }
-
+        /// <summary>
+        /// 原九轴的传感器解析
+        /// </summary>
+        /// <param name="helper"></param>
+        /// <param name="value"></param>
+        /// <param name="characteristic"></param>
         void OnCharacteristicChanged(BluetoothHelper helper, byte[] value, BluetoothHelperCharacteristic characteristic)
         {
             if (helper != _bluetoothHelper) return;
@@ -209,9 +276,71 @@ namespace SmartBowSDK
             if (macAddress == null && _receivedDataCount++ < 500) ParseMacAddress(value);
             smartBowHelper.aimHandler.OnDataReceived(bytes);
         }
+        /// <summary>
+        /// 六轴传感器时候使用的解析
+        /// </summary>
+        /// <param name="helper"></param>
+        /// <param name="value"></param>
+        /// <param name="characteristic"></param>
+        void OnCharacteristicChanged6Axis(BluetoothHelper helper, byte[] value, BluetoothHelperCharacteristic characteristic)
+        {
+            if (helper != _bluetoothHelper) return;
+            if (bluetoothStatus != BluetoothStatusEnum.Connected) return;
+            byte[] bytes = value;
+            if (macAddress == null && _receivedDataCount++ < 500) ParseMacAddress(value);
+            //smartBowHelper.aimHandler.OnDataReceived(bytes);
+            //转字符串后就是 Bat
+            if (bytes.Length == 20  && bytes[19] == 0x0a 
+                //Bat
+                && bytes[2] == 0x42 && bytes[3] == 0x61 && bytes[4] == 0x74) {
+                //第一步 解析电量?
+                string betty = System.Text.Encoding.ASCII.GetString(bytes);
+                // SmartBowLogger.Log(this, BitConverter.ToString(bytes).Replace("-", ""));
+                //SmartBowLogger.Log(this, "betty:" + betty);
+                // 第二步:解析JSON字符串
+                Newtonsoft.Json.Linq.JObject json = Newtonsoft.Json.Linq.JObject.Parse(betty);
+                // 第三步:提取"Bat"的值
+                int batValue = (int)json["Bat"];
+                SmartBowLogger.Log(this, "Bat Value: " + batValue); // 输出: 100
+                battery = batValue;
+            }
+            //传感器数据
+            if (bytes.Length == 20 && bytes[0] == 0x7b && bytes[19] == 0x7d)
+            {
+                o06DOF.SixData sixData = sixAxisFusion.getSixAxisByBytes(bytes);
+                Quaternion quaternion = sixAxisFusion.tranUpdateData(sixData);
+                //输出欧拉角 pitch yaw roll
+                smartBowHelper.InvokeOnSixAxisRotationUpdate(quaternion.eulerAngles);
+                //smartBowHelper.InvokeOnAxisDataUpdateEvent(bytes);
+            }
+        }
+        /// <summary>
+        /// 重置6轴identify
+        /// </summary>
+        public void ResetSixAxisFusion() {
+            if (sixAxisFusion != null) {
+                sixAxisFusion.ResetToInitialRotation();
+            }
+        }
+
+        /// <summary>
+        /// pc调用
+        /// </summary>
+        /// <param name="deviceId"></param>
+        /// <param name="value"></param>
         void OnCharacteristicChanged_windows(string deviceId, byte[] value)
         {
-            OnCharacteristicChanged(null, value, null);
+            if (sensorAxisType == SensorAxisType.SixAxisSensor)
+            {
+                //6轴指令
+                OnCharacteristicChanged6Axis(null, value, null);
+            }
+            else
+            {
+                //九轴
+                OnCharacteristicChanged(null, value, null);
+            }
+
         }
 
         void OnScanEnded(BluetoothHelper helper, LinkedList<BluetoothDevice> nearbyDevices)
@@ -299,6 +428,30 @@ namespace SmartBowSDK
 
         }
 
+        /// <summary>
+        /// 初始化6轴指令
+        /// </summary>
+        /// <returns></returns>
+        IEnumerator InitWhenConnected6Axis()
+        {
+            string myConnectedHandlerID = Guid.NewGuid().ToString();
+            _connectedHandlerID = myConnectedHandlerID;
+            yield return new WaitForSecondsRealtime(BluetoothWindows.IsWindows() ? 0.3f : 2.2f);
+            Queue<string> cmds = new Queue<string>(new string[] { "M", "B", "B" });
+            while (cmds.Count > 0)
+            {
+                if (bluetoothStatus != BluetoothStatusEnum.Connected || myConnectedHandlerID != _connectedHandlerID) yield break;
+                string cmd = cmds.Dequeue();
+                WriteData(cmd);
+                yield return new WaitForSecondsRealtime(0.3f);
+            }
+            if (bluetoothStatus != BluetoothStatusEnum.Connected || myConnectedHandlerID != _connectedHandlerID) yield break;
+            StartCoroutine(LoopRequestBattery6Axis(myConnectedHandlerID));
+            moduleInited = true;
+            smartBowHelper.InvokeOnBluetoothModuleInited();
+
+        }
+
         private int _battery = 0;
         public int battery
         {
@@ -306,10 +459,14 @@ namespace SmartBowSDK
             set
             {
                 _battery = value;
-                SmartBowLogger.Log(this, "Battery缓存成功");
+                //SmartBowLogger.Log(this, "Battery缓存成功");
             }
         }
-
+        /// <summary>
+        /// 九轴原本的连接电池指令
+        /// </summary>
+        /// <param name="myConnectedHandlerID"></param>
+        /// <returns></returns>
         IEnumerator LoopRequestBattery(string myConnectedHandlerID)
         {
             while (bluetoothStatus == BluetoothStatusEnum.Connected && myConnectedHandlerID == _connectedHandlerID)
@@ -318,6 +475,19 @@ namespace SmartBowSDK
                 AddCommandToQueue("b");
             }
         }
+        /// <summary>
+        /// 6轴的连接电池指令
+        /// </summary>
+        /// <param name="myConnectedHandlerID"></param>
+        /// <returns></returns>
+        IEnumerator LoopRequestBattery6Axis(string myConnectedHandlerID)
+        {
+            while (bluetoothStatus == BluetoothStatusEnum.Connected && myConnectedHandlerID == _connectedHandlerID)
+            {
+                yield return new WaitForSecondsRealtime(10);
+                AddCommandToQueue("B");
+            }
+        }
 
         private List<string> _commands = new List<string>();
         void LoopHandleCommands()

+ 18 - 0
SmartBowSDK/SmartBowSDK/BluetoothStatusEnum.cs

@@ -41,4 +41,22 @@
         ARTEMISPro = 1,
         Pistol1 = 2,
     }
+
+    /// <summary>
+    /// 添加一个传感器轴类型。默认的是使用的是九轴
+    /// 因为要连接其他设备。所以添加一个传感器类型来区分数据解析
+    /// </summary>
+    public enum SensorAxisType 
+    {
+        /// <summary>
+        /// 九轴传感器
+        /// </summary>
+        NineAxisSensor = 0,
+
+        /// <summary>
+        /// 六轴传感器
+        /// </summary>
+        SixAxisSensor = 1
+    
+    }
 }

+ 68 - 0
SmartBowSDK/SmartBowSDK/SmartBowHelper.cs

@@ -112,6 +112,17 @@ namespace SmartBowSDK
             }
         }
 
+        /// <summary>
+        /// 设置传感器类型,用来区分解析
+        /// </summary>
+        /// <param name="sensorAxisType"></param>
+        public void SetSensorAxisType(SensorAxisType sensorAxisType) 
+        {
+            bluetoothAim.sensorAxisType = sensorAxisType;
+
+            SmartBowLogger.Log(this, "SetSensorAxisType:" + bluetoothAim.sensorAxisType);
+        }
+
 
         /// <summary>
         /// 连接蓝牙模块
@@ -362,6 +373,7 @@ namespace SmartBowSDK
             aimHandler.DoIdentity();
         }
 
+
         /// <summary>
         /// 监听模块的功能键短按
         /// </summary>
@@ -494,5 +506,61 @@ namespace SmartBowSDK
                 Debug.LogError(e);
             }
         }
+
+        #region 6轴部分接口
+        /// <summary>
+        /// 6轴数据重置初始位置数据
+        /// </summary>
+        public void ResetSixAxisIdentity()
+        {
+            bluetoothAim.ResetSixAxisFusion();
+        }
+        /// <summary>
+        /// 监听姿态角更新
+        /// </summary>
+        public event SixAxisRotationUpdateEvent OnSixAxisRotationUpdate;
+
+        /// <summary>
+        /// 姿态角更新事件
+        /// </summary>
+        /// <param name="rotation">姿态角</param>
+        public delegate void SixAxisRotationUpdateEvent(Vector3 eulerAngles);
+        internal void InvokeOnSixAxisRotationUpdate(Vector3 eulerAngles)
+        {
+            if (bluetoothAim.bluetoothStatus != BluetoothStatusEnum.Connected) return;
+            try
+            {
+                OnSixAxisRotationUpdate?.Invoke(eulerAngles);
+            }
+            catch (Exception e)
+            {
+                Debug.LogError(e);
+            }
+        }
+
+        ///// <summary>
+        ///// 芯片数据更新事件
+        ///// </summary>
+        ///// <param name="rotation">姿态角</param>
+        //public delegate void AxisDataUpdateEvent(byte[] value);
+        //internal void InvokeOnAxisDataUpdateEvent(byte[] value)
+        //{
+        //    if (bluetoothAim.bluetoothStatus != BluetoothStatusEnum.Connected) return;
+        //    try
+        //    {
+        //        OnAxisDataUpdate?.Invoke(value);
+        //    }
+        //    catch (Exception e)
+        //    {
+        //        Debug.LogError(e);
+        //    }
+        //}
+        ///// <summary>
+        ///// 芯片数据更新
+        ///// </summary>
+        //public event AxisDataUpdateEvent OnAxisDataUpdate;
+        #endregion
+
+
     }
 }

+ 183 - 0
SmartBowSDK/SmartBowSDK/o06DOF.cs

@@ -0,0 +1,183 @@
+using ArduinoBluetoothAPI;
+using System;
+using UnityEngine;
+
+
+public class o06DOF
+{
+
+    /////////////////////g       degree/ms         
+    //void Update(Vector3 Acc, Vector3 Gyr, Vector3 Mag, long TimeGap)
+    //{
+    //    if (TimeGap <= 0)
+    //        return;
+    //}
+
+    public class SixAxisFusion
+    {
+        Vector3 acceleratorOffset;
+        Vector3 gyroscopeOffset;
+        float gForce;
+        float gyroscopeToDegree;
+        //float acceleratorRateAsOffset;
+
+        float overallGVectorCredibility = 0;
+        Vector3 previousAccelerator;
+        public Vector3 acceleratorGlobal;
+        public Quaternion quaternion = new Quaternion(0, 0, 0, 1);
+        public Vector3 accelerationNG//with No G force
+        {
+            get
+            {
+                var newQuat = new Quaternion(quaternion.x, quaternion.y, quaternion.z, -quaternion.w);
+                return previousAccelerator - newQuat * new Vector3(0, -gForce, 0);
+            }
+        }
+        public Vector3 speed = Vector3.zero;
+        public Vector3 locus = Vector3.zero;
+        public Vector3 rotation = Vector3.zero;
+        public SixAxisFusion(Vector3 acceleratorOffset, Vector3 gyroscopeOffset, float gForce, float gyroscopeToDegree)
+        {
+            this.acceleratorOffset = acceleratorOffset;// 反向校正
+            this.gyroscopeOffset = gyroscopeOffset;// 反向校正
+            this.gForce = gForce;
+            this.gyroscopeToDegree = gyroscopeToDegree;
+            //this.acceleratorRateAsOffset = acceleratorRateAsOffset;
+
+            previousAccelerator = new Vector3(0, -gForce, 0);
+            acceleratorGlobal = new Vector3(0, -gForce, 0);
+        }
+        Quaternion update(Vector3 accelerator, Vector3 gyroscope)
+        {
+            accelerator += acceleratorOffset;
+            gyroscope += gyroscopeOffset;
+            gyroscope *= gyroscopeToDegree;
+
+            var newQua = new Quaternion();
+            newQua.eulerAngles = gyroscope;
+            // 根据陀螺仪计算新的四元数旋转
+            //var newQua = Quaternion.Euler(gyroscope); // 使用 Euler 角度来生成四元数
+            quaternion = quaternion * newQua;//一定要这样乘
+
+            float gForceCredibility = 1 / (1 + Mathf.Pow((Mathf.Abs(Mathf.Sqrt(accelerator.sqrMagnitude) - gForce) / gForce * 16), 1.0f));
+            float gDegreeCredibility = 1 / (1 + Mathf.Pow(Vector3.Angle(accelerator, newQua * previousAccelerator), 1.0f));
+            overallGVectorCredibility = overallGVectorCredibility * 0.3f + gForceCredibility * gDegreeCredibility * 0.7f;
+            //Debug.Log(Mathf.Pow(overallGVectorCredibility, 0.1f));
+
+            float rotationUnCredibility = Mathf.Pow(1 - 1 / (1 + gyroscope.magnitude), 5);
+            //Debug.Log(rotationUnCredibility);
+
+            acceleratorGlobal = quaternion * accelerator;
+            Vector3 downVector = new Vector3(0, -1, 0);
+            float angle = Vector3.Angle(acceleratorGlobal, downVector);
+            //Vector3 gVector = Vector3.RotateTowards(acceleratorGlobal, downVector, angle / 180 * Mathf.PI * Mathf.Pow(overallGVectorCredibility, 1f) * rotationUnCredibility, 1);//偏移量,从陀螺仪数据往加速计数据的偏移量
+            Vector3 gVector = Vector3.RotateTowards(acceleratorGlobal, downVector, angle / 180 * Mathf.PI * Mathf.Pow(overallGVectorCredibility, 1f) * 0.1f, 1);//偏移量,从陀螺仪数据往加速计数据的偏移量
+                                                                                                                                                                //Vector3 gVector = Vector3.RotateTowards(acceleratorGlobal, downVector, angle / 180 * Mathf.PI * 1, 1);//偏移量,从陀螺仪数据往加速计数据的偏移量
+
+            newQua = new Quaternion();
+            newQua.SetFromToRotation(quaternion * accelerator, gVector);
+            // 使用 SetFromToRotation 进行四元数校正
+           // newQua = Quaternion.FromToRotation(quaternion * accelerator, gVector);
+            quaternion = newQua * quaternion;//一定要反过来乘
+
+            previousAccelerator = accelerator;
+            rotation = gyroscope;
+            speed = speed * 0.95f + accelerationNG;
+            locus = locus * 0.95f + speed;
+            return quaternion;
+        }
+
+        public void ResetToInitialRotation()
+        {
+            quaternion = Quaternion.identity;
+            speed = Vector3.zero;
+            locus = Vector3.zero;
+            rotation = Vector3.zero;
+
+            previousAccelerator = new Vector3(0, -gForce, 0);
+            acceleratorGlobal = new Vector3(0, -gForce, 0);
+
+            Debug.Log("重置到初始状态");
+        }
+        /// <summary>
+        /// 转换成四元数
+        /// </summary>
+        /// <param name="accelerator"></param>
+        /// <param name="gyroscope"></param>
+        /// <returns></returns>
+        public Quaternion tranUpdateData(SixData sixData) {
+            return update(sixData.Acc, sixData.Gryo);
+        }
+
+
+        protected double LastMS;
+        /// <summary>
+        /// 解析处理一个6轴数据
+        /// </summary>
+        /// <param name="bytes"></param>
+        /// <returns></returns>
+        public SixData getSixAxisByBytes(byte[] bytes)
+        {
+            // 获取时间信息
+            int min = bytes[16];
+            int sec = bytes[17];
+            float millis = SNum(bytes[1], bytes[2]);
+            var CurrentMS = (((double)min) * 60 + sec) * 1000 + millis;
+            if (LastMS == default)
+            {
+                LastMS = CurrentMS;
+            }
+            // 计算时间差,以秒为单位
+            var GapMS = CurrentMS - LastMS;
+            LastMS = CurrentMS;
+            double deltaTime = GapMS / 1000.0;  // 转换为秒
+            string handle = bytes[3].ToString();
+            float ax = (SNum(bytes[4], bytes[5]) / 32768 * 16);
+            float ay = (SNum(bytes[6], bytes[7]) / 32768 * 16);
+            float az = (SNum(bytes[8], bytes[9]) / 32768 * 16);
+            float gx = (SNum(bytes[10], bytes[11]) / 32768 * 2000); // 度/秒
+            float gy = (SNum(bytes[12], bytes[13]) / 32768 * 2000); // 度/秒
+            float gz = (SNum(bytes[14], bytes[15]) / 32768 * 2000); // 度/秒
+            string[] parseDataAcc = { ax.ToString("#0.000"), ay.ToString("#0.000"), az.ToString("#0.000") };
+            string[] parseDataGro = { gx.ToString("#0.000"), gy.ToString("#0.000"), gz.ToString("#0.000") };
+            string[] parseDataTime = { min.ToString(), sec.ToString(), millis.ToString() };
+
+            // 计算每帧旋转的角度(角速度 * 时间)
+            float rotationX = gx * (float)deltaTime;  // X轴转动的度数
+            float rotationY = gy * (float)deltaTime;  // Y轴转动的度数
+            float rotationZ = gz * (float)deltaTime;  // Z轴转动的度数
+                                                      //Quaternion quaternion = update(new Vector3(ax, ay, az), new Vector3(rotationX, rotationY, rotationZ));
+                                                      //+ ":Quat:" + quaternion 
+                                                      // Debug.Log("数据:Acc[" + string.Join(", ", parseDataAcc) + "] Gryo:" + string.Join(", ", parseDataGro) + "]. Time:" + string.Join(", ", parseDataTime) + ",Euler:" + quaternion.eulerAngles);
+            return new SixData(new Vector3(ax, ay, az), new Vector3(rotationX, rotationY, rotationZ), min, sec, millis);
+        }
+        float SNum(byte b1, byte b2)
+        {
+            ushort twoByte = (ushort)(b1 * 256 + b2);
+            short shortNum = (short)twoByte;
+            return (float)shortNum;
+        }
+    }
+
+   
+    /// <summary>
+    /// 解析转换的6轴格式
+    /// </summary>
+    public class SixData
+    {
+        public Vector3 Acc;
+        public Vector3 Gryo;
+        public int Min;
+        public int Sec;
+        public float Millis;
+
+        public SixData(Vector3 acc, Vector3 gyro, int min, int sec, float millis)
+        {
+            Acc = acc;
+            Gryo = gyro;
+            Min = min;
+            Sec = sec;
+            Millis = millis;
+        }
+    }
+}

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است