From d97c3fee148fe223357cf37289fa430f75a149b7 Mon Sep 17 00:00:00 2001 From: Kenneth Yang Date: Fri, 6 Sep 2024 15:30:19 -0700 Subject: [PATCH 1/6] State hooks and display --- ...BehaviorController_Automation_Insertion.cs | 15 +++-- .../AutomationStackHandler_Insertion.cs | 13 +---- .../Scripts/UI/States/AutomationStackState.cs | 56 +++++++++++++++++++ Assets/UI/Components/AutomationStack.uxml | 9 +++ 4 files changed, 77 insertions(+), 16 deletions(-) diff --git a/Assets/Scripts/Pinpoint/Probes/ManipulatorBehaviorController/ManipulatorBehaviorController_Automation_Insertion.cs b/Assets/Scripts/Pinpoint/Probes/ManipulatorBehaviorController/ManipulatorBehaviorController_Automation_Insertion.cs index c7005280..62386a4c 100644 --- a/Assets/Scripts/Pinpoint/Probes/ManipulatorBehaviorController/ManipulatorBehaviorController_Automation_Insertion.cs +++ b/Assets/Scripts/Pinpoint/Probes/ManipulatorBehaviorController/ManipulatorBehaviorController_Automation_Insertion.cs @@ -36,11 +36,6 @@ public partial class ManipulatorBehaviorController /// private const int EXIT_DRIVE_SPEED_MULTIPLIER = 6; - /// - /// Speed multiplier of the probe once outside the brain. - /// - private const int OUTSIDE_DRIVE_SPEED_MULTIPLIER = 50; - #endregion #endregion @@ -479,6 +474,16 @@ private float GetTargetDepth(ProbeManager targetInsertionProbeManager) return _duraDepth + GetTargetDistanceToDura(targetInsertionProbeManager); } + /// + /// Compute the ETA for a probe to reach a target insertion (or exit). + /// + /// Target to calculate ETA to. + /// MM:SS format ETA for reaching a target or exiting, based on the probe's state. + public string GetETA(ProbeManager targetInsertionProbeManager) + { + return ""; + } + #endregion } } diff --git a/Assets/Scripts/UI/AutomationStack/AutomationStackHandler_Insertion.cs b/Assets/Scripts/UI/AutomationStack/AutomationStackHandler_Insertion.cs index 0d10162f..c1decbf0 100644 --- a/Assets/Scripts/UI/AutomationStack/AutomationStackHandler_Insertion.cs +++ b/Assets/Scripts/UI/AutomationStack/AutomationStackHandler_Insertion.cs @@ -1,5 +1,4 @@ using System; -using System.Linq; using UnityEngine.UIElements; namespace UI.AutomationStack @@ -11,14 +10,6 @@ public partial class AutomationStackHandler { #region Properties - /// - /// Compute the target insertion probe manager from selected target insertion index. - /// - private ProbeManager TargetInsertionProbeManager => - _state.SurfaceCoordinateStringToTargetInsertionOptionProbeManagers[ - _state.TargetInsertionOptions.ElementAt(_state.SelectedTargetInsertionIndex) - ]; - /// /// Compute the base speed from selected base speed index. /// @@ -49,7 +40,7 @@ private partial void OnDriveToTargetInsertionButtonPressed() // Call drive. ActiveManipulatorBehaviorController.Drive( - TargetInsertionProbeManager, + _state.TargetInsertionProbeManager, BaseSpeed, _state.DrivePastTargetDistance / 1000f ); @@ -76,7 +67,7 @@ private partial void OnExitButtonPressed() ); // Call exit. - ActiveManipulatorBehaviorController.Exit(TargetInsertionProbeManager, BaseSpeed); + ActiveManipulatorBehaviorController.Exit(_state.TargetInsertionProbeManager, BaseSpeed); } #endregion diff --git a/Assets/Scripts/UI/States/AutomationStackState.cs b/Assets/Scripts/UI/States/AutomationStackState.cs index fc82ea68..61aea935 100644 --- a/Assets/Scripts/UI/States/AutomationStackState.cs +++ b/Assets/Scripts/UI/States/AutomationStackState.cs @@ -237,6 +237,16 @@ out var selectedTargetInsertionProbeManager #region Option List helpers + /// + /// Compute the target insertion probe manager from selected target insertion index. + /// + public ProbeManager TargetInsertionProbeManager => + SelectedTargetInsertionIndex > 0 + ? SurfaceCoordinateStringToTargetInsertionOptionProbeManagers[ + TargetInsertionOptions.ElementAt(SelectedTargetInsertionIndex) + ] + : null; + /// /// Expose mapping from target insertion option probe manager to surface coordinate string. /// @@ -410,11 +420,27 @@ public float DuraCalibrationOffset #region Insertion + /// + /// Is the base speed radio group enabled for editing. + /// + /// True when the selected probe is Ephys Link controlled and not moving, false otherwise. + [CreateProperty] + public bool IsBaseSpeedRadioGroupEnabled => + IsEnabled && !ActiveManipulatorBehaviorController.IsMoving; + /// /// Selection index in radio button group for base insertion speed. /// public int SelectedBaseSpeedIndex; + /// + /// Is the custom base speed field enabled. + /// + /// True when the selected probe is Ephys Link controlled and not moving, false otherwise. + [CreateProperty] + public bool IsCustomBaseSpeedEnabled => + IsEnabled && !ActiveManipulatorBehaviorController.IsMoving; + /// /// Custom base insertion speed (µm/s). /// @@ -429,6 +455,14 @@ public float DuraCalibrationOffset public DisplayStyle CustomInsertionBaseSpeedDisplayStyle => SelectedBaseSpeedIndex == 4 ? DisplayStyle.Flex : DisplayStyle.None; + /// + /// Is the drive past target distance field enabled. + /// + /// True when the selected probe is Ephys Link controlled and not moving, false otherwise. + [CreateProperty] + public bool IsDrivePastTargetDistanceEnabled => + IsEnabled && !ActiveManipulatorBehaviorController.IsMoving; + /// /// Distance to drive past the target insertion depth (µm). /// @@ -503,6 +537,28 @@ public float DuraCalibrationOffset ? DisplayStyle.Flex : DisplayStyle.None; + [CreateProperty] + public string ETA => + IsEnabled && SelectedTargetInsertionIndex > 0 + ? $"ETA: {ActiveManipulatorBehaviorController.GetETA(TargetInsertionProbeManager)}" + : "ETA: N/A"; + + /// + /// Visibility of the ETA label. + /// + /// + /// Shown only when selected/active probe is Ephys Link controlled, the probe is moving, and the probe is in the + /// brain. + /// + [CreateProperty] + public DisplayStyle ETADisplayStyle => + IsEnabled + && ActiveManipulatorBehaviorController.IsMoving + && ActiveProbeAutomationStateManager.ProbeAutomationState + >= ProbeAutomationState.AtDuraInsert + ? DisplayStyle.Flex + : DisplayStyle.None; + #endregion } } diff --git a/Assets/UI/Components/AutomationStack.uxml b/Assets/UI/Components/AutomationStack.uxml index 5331b348..b401e8fb 100644 --- a/Assets/UI/Components/AutomationStack.uxml +++ b/Assets/UI/Components/AutomationStack.uxml @@ -68,17 +68,20 @@ + + + @@ -100,6 +103,12 @@ + + + + + + From 6ebb496322ba2db9db5ff11e47b78bf251b97beb Mon Sep 17 00:00:00 2001 From: Kenneth Yang Date: Fri, 6 Sep 2024 17:34:50 -0700 Subject: [PATCH 2/6] Upgrade VBL packages, add JS functions --- Assets/Plugins/unity_js_link.jslib | 8 ++++++++ Packages/packages-lock.json | 4 ++-- ProjectSettings/ProjectSettings.asset | 8 +++++--- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Assets/Plugins/unity_js_link.jslib b/Assets/Plugins/unity_js_link.jslib index 2005faa1..c7c71e2a 100644 --- a/Assets/Plugins/unity_js_link.jslib +++ b/Assets/Plugins/unity_js_link.jslib @@ -5,6 +5,14 @@ mergeInto(LibraryManager.library, { console.log('copy2clipboard called: ' + str); copy2clipboardStr = str; canvas.addEventListener('click', copy2clipboardCallback, false); + }, + + SelectPID: function (pid) { + window.alert(UTF8ToString(pid)); + }, + + DownloadFile: function(filename, filedata) { + downloadFile(filename, filedata); } }); \ No newline at end of file diff --git a/Packages/packages-lock.json b/Packages/packages-lock.json index c061efc9..f4ef3869 100644 --- a/Packages/packages-lock.json +++ b/Packages/packages-lock.json @@ -266,14 +266,14 @@ "depth": 0, "source": "git", "dependencies": {}, - "hash": "2cf554dbd3b8baa5200d701f6e0403b119b8ecbf" + "hash": "d95427c01958f0e731dd96e2658e71fa3d672e2b" }, "vbl.urchin": { "version": "https://github.com/VirtualBrainLab/Urchin.git?path=/UnityClient/Packages/vbl.urchin", "depth": 0, "source": "git", "dependencies": {}, - "hash": "e088d37b2d264720200bcace3d0ae5d658763044" + "hash": "41dd138f9a929c243a89a5b00e0b8d70a7e72864" }, "com.unity.modules.accessibility": { "version": "1.0.0", diff --git a/ProjectSettings/ProjectSettings.asset b/ProjectSettings/ProjectSettings.asset index 4ba114ab..8e478148 100644 --- a/ProjectSettings/ProjectSettings.asset +++ b/ProjectSettings/ProjectSettings.asset @@ -82,7 +82,6 @@ PlayerSettings: defaultIsNativeResolution: 1 macRetinaSupport: 1 runInBackground: 1 - captureSingleScreen: 0 muteOtherAudioSources: 0 Prepare IOS For Recording: 0 Force IOS Speakers When Recording: 0 @@ -140,7 +139,7 @@ PlayerSettings: loadStoreDebugModeEnabled: 0 visionOSBundleVersion: 1.0 tvOSBundleVersion: 1.0 - bundleVersion: 1.2 + bundleVersion: 2.0 preloadedAssets: - {fileID: 11400000, guid: 6057f25234ce83a4bbb3ae618a501907, type: 2} metroInputSource: 0 @@ -427,7 +426,10 @@ PlayerSettings: m_BuildTargetGroupLightmapSettings: [] m_BuildTargetGroupLoadStoreDebugModeSettings: [] m_BuildTargetNormalMapEncoding: [] - m_BuildTargetDefaultTextureCompressionFormat: [] + m_BuildTargetDefaultTextureCompressionFormat: + - serializedVersion: 3 + m_BuildTarget: WebGL + m_Formats: 05000000 playModeTestRunnerEnabled: 0 runPlayModeTestAsEditModeTest: 0 actionOnDotNetUnhandledException: 1 From 0499d03a0058c9455c337037dde35b36400e5d9e Mon Sep 17 00:00:00 2001 From: Kenneth Yang Date: Sat, 7 Sep 2024 19:49:37 -0700 Subject: [PATCH 3/6] WIP bad ETA, depth is not right? --- ...BehaviorController_Automation_Insertion.cs | 47 ++++++++++++++++++- .../AutomationStackHandler_Insertion.cs | 21 +-------- .../Scripts/UI/States/AutomationStackState.cs | 15 +++++- 3 files changed, 61 insertions(+), 22 deletions(-) diff --git a/Assets/Scripts/Pinpoint/Probes/ManipulatorBehaviorController/ManipulatorBehaviorController_Automation_Insertion.cs b/Assets/Scripts/Pinpoint/Probes/ManipulatorBehaviorController/ManipulatorBehaviorController_Automation_Insertion.cs index 49c3623c..f6f157a7 100644 --- a/Assets/Scripts/Pinpoint/Probes/ManipulatorBehaviorController/ManipulatorBehaviorController_Automation_Insertion.cs +++ b/Assets/Scripts/Pinpoint/Probes/ManipulatorBehaviorController/ManipulatorBehaviorController_Automation_Insertion.cs @@ -464,10 +464,53 @@ private float GetTargetDepth(ProbeManager targetInsertionProbeManager) /// Compute the ETA for a probe to reach a target insertion (or exit). /// /// Target to calculate ETA to. + /// Base driving speed in mm/s. + /// Distance to drive past target in mm. /// MM:SS format ETA for reaching a target or exiting, based on the probe's state. - public string GetETA(ProbeManager targetInsertionProbeManager) + public string GetETA( + ProbeManager targetInsertionProbeManager, + float baseSpeed, + float drivePastDistance + ) { - return ""; + // Get current distance to target. + var distanceToTarget = GetCurrentDistanceToTarget(targetInsertionProbeManager); + + // Compute ETA. + var secondsToDestination = ProbeAutomationStateManager.ProbeAutomationState switch + { + ProbeAutomationState.DrivingToNearTarget + => Mathf.Max(0, distanceToTarget - NEAR_TARGET_DISTANCE) / baseSpeed + + (NEAR_TARGET_DISTANCE + 2 * drivePastDistance) + / (baseSpeed * NEAR_TARGET_SPEED_MULTIPLIER), + ProbeAutomationState.DrivingToPastTarget + => (distanceToTarget + 2 * drivePastDistance) + / (baseSpeed * NEAR_TARGET_SPEED_MULTIPLIER), + ProbeAutomationState.ReturningToTarget + => distanceToTarget / (baseSpeed * NEAR_TARGET_SPEED_MULTIPLIER), + ProbeAutomationState.ExitingToDura + => (GetTargetDistanceToDura(targetInsertionProbeManager) - distanceToTarget) + / baseSpeed + * EXIT_DRIVE_SPEED_MULTIPLIER + + DURA_MARGIN_DISTANCE / (baseSpeed * EXIT_DRIVE_SPEED_MULTIPLIER) + + ENTRY_COORDINATE_DURA_DISTANCE / AUTOMATIC_MOVEMENT_SPEED, + ProbeAutomationState.ExitingToMargin + => ( + DURA_MARGIN_DISTANCE + - distanceToTarget + - GetTargetDistanceToDura(targetInsertionProbeManager) + ) / (baseSpeed * EXIT_DRIVE_SPEED_MULTIPLIER) + + ENTRY_COORDINATE_DURA_DISTANCE / AUTOMATIC_MOVEMENT_SPEED, + ProbeAutomationState.ExitingToTargetEntryCoordinate + => ( + ENTRY_COORDINATE_DURA_DISTANCE + - distanceToTarget + - GetTargetDistanceToDura(targetInsertionProbeManager) + ) / AUTOMATIC_MOVEMENT_SPEED, + _ => 0 + }; + + return TimeSpan.FromSeconds(secondsToDestination).ToString(@"mm\:ss"); } #endregion diff --git a/Assets/Scripts/UI/AutomationStack/AutomationStackHandler_Insertion.cs b/Assets/Scripts/UI/AutomationStack/AutomationStackHandler_Insertion.cs index c1decbf0..b102b6f7 100644 --- a/Assets/Scripts/UI/AutomationStack/AutomationStackHandler_Insertion.cs +++ b/Assets/Scripts/UI/AutomationStack/AutomationStackHandler_Insertion.cs @@ -8,23 +8,6 @@ namespace UI.AutomationStack /// public partial class AutomationStackHandler { - #region Properties - - /// - /// Compute the base speed from selected base speed index. - /// - private float BaseSpeed => - _state.SelectedBaseSpeedIndex switch - { - 0 => 0.002f, - 1 => 0.005f, - 2 => 0.01f, - 3 => 0.5f, - _ => _state.CustomBaseSpeed / 1000f - }; - - #endregion - #region Implementations private partial void OnDriveToTargetInsertionButtonPressed() @@ -41,7 +24,7 @@ private partial void OnDriveToTargetInsertionButtonPressed() // Call drive. ActiveManipulatorBehaviorController.Drive( _state.TargetInsertionProbeManager, - BaseSpeed, + _state.BaseSpeed, _state.DrivePastTargetDistance / 1000f ); } @@ -67,7 +50,7 @@ private partial void OnExitButtonPressed() ); // Call exit. - ActiveManipulatorBehaviorController.Exit(_state.TargetInsertionProbeManager, BaseSpeed); + ActiveManipulatorBehaviorController.Exit(_state.TargetInsertionProbeManager, _state.BaseSpeed); } #endregion diff --git a/Assets/Scripts/UI/States/AutomationStackState.cs b/Assets/Scripts/UI/States/AutomationStackState.cs index 61aea935..2e1b710b 100644 --- a/Assets/Scripts/UI/States/AutomationStackState.cs +++ b/Assets/Scripts/UI/States/AutomationStackState.cs @@ -447,6 +447,19 @@ public float DuraCalibrationOffset /// Should only be used when is on "Custom" index. public int CustomBaseSpeed; + /// + /// Compute the base speed from selected base speed index. + /// + public float BaseSpeed => + SelectedBaseSpeedIndex switch + { + 0 => 0.002f, + 1 => 0.005f, + 2 => 0.01f, + 3 => 0.5f, + _ => CustomBaseSpeed / 1000f + }; + /// /// Visibility of the custom insertion base speed field. /// @@ -540,7 +553,7 @@ public float DuraCalibrationOffset [CreateProperty] public string ETA => IsEnabled && SelectedTargetInsertionIndex > 0 - ? $"ETA: {ActiveManipulatorBehaviorController.GetETA(TargetInsertionProbeManager)}" + ? $"ETA: {ActiveManipulatorBehaviorController.GetETA(TargetInsertionProbeManager, BaseSpeed, DrivePastTargetDistance)}" : "ETA: N/A"; /// From b5a6b47e8b57563cab816c8fd20cd50168c32a3a Mon Sep 17 00:00:00 2001 From: Kenneth Yang Date: Tue, 17 Sep 2024 16:10:45 -0700 Subject: [PATCH 4/6] Fixed depth calculation --- ...orController_Automation_DuraCalibration.cs | 8 +++++--- ...BehaviorController_Automation_Insertion.cs | 20 +------------------ 2 files changed, 6 insertions(+), 22 deletions(-) diff --git a/Assets/Scripts/Pinpoint/Probes/ManipulatorBehaviorController/ManipulatorBehaviorController_Automation_DuraCalibration.cs b/Assets/Scripts/Pinpoint/Probes/ManipulatorBehaviorController/ManipulatorBehaviorController_Automation_DuraCalibration.cs index 0ded0617..e59d481d 100644 --- a/Assets/Scripts/Pinpoint/Probes/ManipulatorBehaviorController/ManipulatorBehaviorController_Automation_DuraCalibration.cs +++ b/Assets/Scripts/Pinpoint/Probes/ManipulatorBehaviorController/ManipulatorBehaviorController_Automation_DuraCalibration.cs @@ -39,6 +39,9 @@ public async Awaitable ResetDuraOffset() var positionResponse = await CommunicationManager.Instance.GetPosition(ManipulatorID); if (CommunicationManager.HasError(positionResponse.Error)) return false; + + // Save the Dura's position. + _duraDepth = positionResponse.Position.w; // Check if there is enough room for exit margin. var continueWithDuraResetCompletionSource = new AwaitableCompletionSource(); @@ -74,10 +77,9 @@ public async Awaitable ResetDuraOffset() // Force update probe position. await UpdateProbePositionFromManipulator(); - // Save the Dura's position. - _duraDepth = positionResponse.Position.w; + // Save the probe's coordinates at the Dura. _duraCoordinate = _probeController.Insertion.APMLDV; - + // Log the event. OutputLog.Log( new[] diff --git a/Assets/Scripts/Pinpoint/Probes/ManipulatorBehaviorController/ManipulatorBehaviorController_Automation_Insertion.cs b/Assets/Scripts/Pinpoint/Probes/ManipulatorBehaviorController/ManipulatorBehaviorController_Automation_Insertion.cs index f6f157a7..ab73f56a 100644 --- a/Assets/Scripts/Pinpoint/Probes/ManipulatorBehaviorController/ManipulatorBehaviorController_Automation_Insertion.cs +++ b/Assets/Scripts/Pinpoint/Probes/ManipulatorBehaviorController/ManipulatorBehaviorController_Automation_Insertion.cs @@ -48,13 +48,6 @@ public partial class ManipulatorBehaviorController /// Used to identify which buttons should be made available. public bool IsMoving { get; private set; } - #region Caches - - private Vector3 _cachedTargetCoordinate = Vector3.negativeInfinity; - private Vector3 _cachedOffsetAdjustedTargetCoordinate = Vector3.negativeInfinity; - - #endregion - #endregion #region Drive Functions @@ -390,13 +383,6 @@ private Vector3 GetOffsetAdjustedTargetCoordinate(ProbeManager targetInsertionPr // Extract target insertion. var targetInsertion = targetInsertionProbeManager.ProbeController.Insertion; - // Shortcut exit if already computed and targetInsertion did not change. - if ( - targetInsertion.APMLDV == _cachedTargetCoordinate - && !float.IsNegativeInfinity(_cachedOffsetAdjustedTargetCoordinate.x) - ) - return _cachedOffsetAdjustedTargetCoordinate; - var targetWorldT = targetInsertion.PositionWorldT(); var relativePositionWorldT = _probeController.Insertion.PositionWorldT() - targetWorldT; var probeTipTForward = _probeController.ProbeTipT.forward; @@ -417,11 +403,7 @@ private Vector3 GetOffsetAdjustedTargetCoordinate(ProbeManager targetInsertionPr offsetAdjustedTargetCoordinateAtlasT ); - // Cache the computed values. - _cachedTargetCoordinate = targetInsertion.APMLDV; - _cachedOffsetAdjustedTargetCoordinate = offsetAdjustedTargetCoordinateT; - - return _cachedOffsetAdjustedTargetCoordinate; + return offsetAdjustedTargetCoordinateT; } /// From cbd1918ae9597fb73c7c83357797c21305338c4c Mon Sep 17 00:00:00 2001 From: Kenneth Yang Date: Tue, 17 Sep 2024 17:00:05 -0700 Subject: [PATCH 5/6] Fixed ETA calculation, need to use computed travel distance to entry --- ...BehaviorController_Automation_Insertion.cs | 25 ++++++++----------- .../AutomationStackHandler_Insertion.cs | 2 +- .../UI/States/AutomationStackState.asset | 2 +- .../Scripts/UI/States/AutomationStackState.cs | 15 +++++++++-- Assets/UI/Components/AutomationStack.uxml | 2 +- 5 files changed, 27 insertions(+), 19 deletions(-) diff --git a/Assets/Scripts/Pinpoint/Probes/ManipulatorBehaviorController/ManipulatorBehaviorController_Automation_Insertion.cs b/Assets/Scripts/Pinpoint/Probes/ManipulatorBehaviorController/ManipulatorBehaviorController_Automation_Insertion.cs index ab73f56a..8b5f0fa4 100644 --- a/Assets/Scripts/Pinpoint/Probes/ManipulatorBehaviorController/ManipulatorBehaviorController_Automation_Insertion.cs +++ b/Assets/Scripts/Pinpoint/Probes/ManipulatorBehaviorController/ManipulatorBehaviorController_Automation_Insertion.cs @@ -462,32 +462,29 @@ float drivePastDistance var secondsToDestination = ProbeAutomationStateManager.ProbeAutomationState switch { ProbeAutomationState.DrivingToNearTarget - => Mathf.Max(0, distanceToTarget - NEAR_TARGET_DISTANCE) / baseSpeed + => Mathf.Max(0, distanceToTarget - NEAR_TARGET_DISTANCE) / baseSpeed // To near target. + (NEAR_TARGET_DISTANCE + 2 * drivePastDistance) - / (baseSpeed * NEAR_TARGET_SPEED_MULTIPLIER), + / (baseSpeed * NEAR_TARGET_SPEED_MULTIPLIER), // To past target and back to target. ProbeAutomationState.DrivingToPastTarget => (distanceToTarget + 2 * drivePastDistance) - / (baseSpeed * NEAR_TARGET_SPEED_MULTIPLIER), + / (baseSpeed * NEAR_TARGET_SPEED_MULTIPLIER), // To past target and back to target. ProbeAutomationState.ReturningToTarget - => distanceToTarget / (baseSpeed * NEAR_TARGET_SPEED_MULTIPLIER), + => distanceToTarget / (baseSpeed * NEAR_TARGET_SPEED_MULTIPLIER), // Back to target. ProbeAutomationState.ExitingToDura => (GetTargetDistanceToDura(targetInsertionProbeManager) - distanceToTarget) - / baseSpeed - * EXIT_DRIVE_SPEED_MULTIPLIER - + DURA_MARGIN_DISTANCE / (baseSpeed * EXIT_DRIVE_SPEED_MULTIPLIER) - + ENTRY_COORDINATE_DURA_DISTANCE / AUTOMATIC_MOVEMENT_SPEED, + / (baseSpeed * EXIT_DRIVE_SPEED_MULTIPLIER) // To Dura. + + DURA_MARGIN_DISTANCE / (baseSpeed * EXIT_DRIVE_SPEED_MULTIPLIER) // To exit margin. + + ENTRY_COORDINATE_DURA_DISTANCE / AUTOMATIC_MOVEMENT_SPEED, // To entry coordinate. ProbeAutomationState.ExitingToMargin => ( DURA_MARGIN_DISTANCE - - distanceToTarget - - GetTargetDistanceToDura(targetInsertionProbeManager) - ) / (baseSpeed * EXIT_DRIVE_SPEED_MULTIPLIER) - + ENTRY_COORDINATE_DURA_DISTANCE / AUTOMATIC_MOVEMENT_SPEED, + - (distanceToTarget - GetTargetDistanceToDura(targetInsertionProbeManager)) + ) / (baseSpeed * EXIT_DRIVE_SPEED_MULTIPLIER) // To exit margin. + + ENTRY_COORDINATE_DURA_DISTANCE / AUTOMATIC_MOVEMENT_SPEED, // To entry coordinate. ProbeAutomationState.ExitingToTargetEntryCoordinate => ( ENTRY_COORDINATE_DURA_DISTANCE - - distanceToTarget - - GetTargetDistanceToDura(targetInsertionProbeManager) + - (distanceToTarget - GetTargetDistanceToDura(targetInsertionProbeManager)) ) / AUTOMATIC_MOVEMENT_SPEED, _ => 0 }; diff --git a/Assets/Scripts/UI/AutomationStack/AutomationStackHandler_Insertion.cs b/Assets/Scripts/UI/AutomationStack/AutomationStackHandler_Insertion.cs index b102b6f7..cd50941d 100644 --- a/Assets/Scripts/UI/AutomationStack/AutomationStackHandler_Insertion.cs +++ b/Assets/Scripts/UI/AutomationStack/AutomationStackHandler_Insertion.cs @@ -25,7 +25,7 @@ private partial void OnDriveToTargetInsertionButtonPressed() ActiveManipulatorBehaviorController.Drive( _state.TargetInsertionProbeManager, _state.BaseSpeed, - _state.DrivePastTargetDistance / 1000f + _state.DrivePastTargetDistanceMillimeters / 1000f ); } diff --git a/Assets/Scripts/UI/States/AutomationStackState.asset b/Assets/Scripts/UI/States/AutomationStackState.asset index 21170fe1..8f19a0dd 100644 --- a/Assets/Scripts/UI/States/AutomationStackState.asset +++ b/Assets/Scripts/UI/States/AutomationStackState.asset @@ -14,4 +14,4 @@ MonoBehaviour: m_EditorClassIdentifier: SelectedBaseSpeedIndex: 1 CustomBaseSpeed: 20 - DrivePastTargetDistance: 50 + DrivePastTargetDistanceMillimeters: 0.05 diff --git a/Assets/Scripts/UI/States/AutomationStackState.cs b/Assets/Scripts/UI/States/AutomationStackState.cs index 2e1b710b..5df9212b 100644 --- a/Assets/Scripts/UI/States/AutomationStackState.cs +++ b/Assets/Scripts/UI/States/AutomationStackState.cs @@ -476,10 +476,21 @@ public float DuraCalibrationOffset public bool IsDrivePastTargetDistanceEnabled => IsEnabled && !ActiveManipulatorBehaviorController.IsMoving; + /// + /// Distance to drive past the target insertion depth (mm). + /// + public float DrivePastTargetDistanceMillimeters; + /// /// Distance to drive past the target insertion depth (µm). /// - public int DrivePastTargetDistance; + /// Used in UI since these are small numbers. + [CreateProperty] + public int DrivePastTargetDistanceMicrometers + { + get => Mathf.RoundToInt(DrivePastTargetDistanceMillimeters * 1000); + set => DrivePastTargetDistanceMillimeters = value / 1000f; + } /// /// Is the drive to target insertion button enabled. @@ -553,7 +564,7 @@ public float DuraCalibrationOffset [CreateProperty] public string ETA => IsEnabled && SelectedTargetInsertionIndex > 0 - ? $"ETA: {ActiveManipulatorBehaviorController.GetETA(TargetInsertionProbeManager, BaseSpeed, DrivePastTargetDistance)}" + ? $"ETA: {ActiveManipulatorBehaviorController.GetETA(TargetInsertionProbeManager, BaseSpeed, DrivePastTargetDistanceMillimeters)}" : "ETA: N/A"; /// diff --git a/Assets/UI/Components/AutomationStack.uxml b/Assets/UI/Components/AutomationStack.uxml index b401e8fb..b3273085 100644 --- a/Assets/UI/Components/AutomationStack.uxml +++ b/Assets/UI/Components/AutomationStack.uxml @@ -80,7 +80,7 @@ - + From 7931b91d409ee2014920d2c8b3030baa87b77628 Mon Sep 17 00:00:00 2001 From: Kenneth Yang Date: Sun, 22 Sep 2024 12:37:43 -0700 Subject: [PATCH 6/6] Drive timer --- ...BehaviorController_Automation_Insertion.cs | 28 ++++++----------- ...orController_Automation_TargetInsertion.cs | 30 +++++++++++++++---- .../AutomationStackHandler_Insertion.cs | 2 +- Assets/UI/Components/AutomationStack.uxml | 11 ++++--- 4 files changed, 40 insertions(+), 31 deletions(-) diff --git a/Assets/Scripts/Pinpoint/Probes/ManipulatorBehaviorController/ManipulatorBehaviorController_Automation_Insertion.cs b/Assets/Scripts/Pinpoint/Probes/ManipulatorBehaviorController/ManipulatorBehaviorController_Automation_Insertion.cs index 8b5f0fa4..8e134789 100644 --- a/Assets/Scripts/Pinpoint/Probes/ManipulatorBehaviorController/ManipulatorBehaviorController_Automation_Insertion.cs +++ b/Assets/Scripts/Pinpoint/Probes/ManipulatorBehaviorController/ManipulatorBehaviorController_Automation_Insertion.cs @@ -48,6 +48,8 @@ public partial class ManipulatorBehaviorController /// Used to identify which buttons should be made available. public bool IsMoving { get; private set; } + private float _actualExitMarginToDuraDistance => _duraDepth - _entryCoordinateDepth; + #endregion #region Drive Functions @@ -98,9 +100,6 @@ float drivePastDistance > NEAR_TARGET_DISTANCE ) { - print( - $"{ProbeAutomationStateManager.ProbeAutomationState}: Going to {targetDepth - NEAR_TARGET_DISTANCE}" - ); var driveToNearTargetResponse = await CommunicationManager.Instance.SetDepth( new SetDepthRequest( @@ -110,8 +109,6 @@ await CommunicationManager.Instance.SetDepth( ) ); - print($"At {driveToNearTargetResponse.Depth}"); - // Shortcut exit if there was an error. if (CommunicationManager.HasError(driveToNearTargetResponse.Error)) return; @@ -119,9 +116,6 @@ await CommunicationManager.Instance.SetDepth( break; case ProbeAutomationState.DrivingToPastTarget: - print( - $"{ProbeAutomationStateManager.ProbeAutomationState}: Going to {targetDepth + drivePastDistance}" - ); // Drive to past target. var driveToPastTargetResponse = await CommunicationManager.Instance.SetDepth( @@ -132,16 +126,11 @@ await CommunicationManager.Instance.SetDepth( ) ); - print($"At {driveToPastTargetResponse.Depth}"); - // Shortcut exit if there was an error. if (CommunicationManager.HasError(driveToPastTargetResponse.Error)) return; break; case ProbeAutomationState.ReturningToTarget: - print( - $"{ProbeAutomationStateManager.ProbeAutomationState}: Going to {targetDepth}" - ); // Drive up to target. var returnToTargetResponse = await CommunicationManager.Instance.SetDepth( new SetDepthRequest( @@ -151,8 +140,6 @@ await CommunicationManager.Instance.SetDepth( ) ); - print($"At {returnToTargetResponse.Depth}"); - // Shortcut exit if there was an error. if (CommunicationManager.HasError(returnToTargetResponse.Error)) return; @@ -474,22 +461,25 @@ float drivePastDistance => (GetTargetDistanceToDura(targetInsertionProbeManager) - distanceToTarget) / (baseSpeed * EXIT_DRIVE_SPEED_MULTIPLIER) // To Dura. + DURA_MARGIN_DISTANCE / (baseSpeed * EXIT_DRIVE_SPEED_MULTIPLIER) // To exit margin. - + ENTRY_COORDINATE_DURA_DISTANCE / AUTOMATIC_MOVEMENT_SPEED, // To entry coordinate. + + _actualExitMarginToDuraDistance / AUTOMATIC_MOVEMENT_SPEED, // To entry coordinate. ProbeAutomationState.ExitingToMargin => ( DURA_MARGIN_DISTANCE - (distanceToTarget - GetTargetDistanceToDura(targetInsertionProbeManager)) ) / (baseSpeed * EXIT_DRIVE_SPEED_MULTIPLIER) // To exit margin. - + ENTRY_COORDINATE_DURA_DISTANCE / AUTOMATIC_MOVEMENT_SPEED, // To entry coordinate. + + _actualExitMarginToDuraDistance / AUTOMATIC_MOVEMENT_SPEED, // To entry coordinate. ProbeAutomationState.ExitingToTargetEntryCoordinate => ( - ENTRY_COORDINATE_DURA_DISTANCE + IDEAL_ENTRY_COORDINATE_TO_DURA_DISTANCE - (distanceToTarget - GetTargetDistanceToDura(targetInsertionProbeManager)) ) / AUTOMATIC_MOVEMENT_SPEED, _ => 0 }; - return TimeSpan.FromSeconds(secondsToDestination).ToString(@"mm\:ss"); + // Return formatted time if above 1 minute. + return secondsToDestination < 60 + ? secondsToDestination.ToString("F1") + : TimeSpan.FromSeconds(secondsToDestination).ToString(@"mm\:ss"); } #endregion diff --git a/Assets/Scripts/Pinpoint/Probes/ManipulatorBehaviorController/ManipulatorBehaviorController_Automation_TargetInsertion.cs b/Assets/Scripts/Pinpoint/Probes/ManipulatorBehaviorController/ManipulatorBehaviorController_Automation_TargetInsertion.cs index 1c9fefb6..0279209d 100644 --- a/Assets/Scripts/Pinpoint/Probes/ManipulatorBehaviorController/ManipulatorBehaviorController_Automation_TargetInsertion.cs +++ b/Assets/Scripts/Pinpoint/Probes/ManipulatorBehaviorController/ManipulatorBehaviorController_Automation_TargetInsertion.cs @@ -25,7 +25,7 @@ public partial class ManipulatorBehaviorController /// /// Distance from the entry coordinate to the Dura. This is considered a safe distance to put the probe. /// - private const float ENTRY_COORDINATE_DURA_DISTANCE = 3.5f; + private const float IDEAL_ENTRY_COORDINATE_TO_DURA_DISTANCE = 3.5f; #endregion @@ -48,6 +48,12 @@ public partial class ManipulatorBehaviorController Vector3.negativeInfinity ); + /// + /// Record the depth at the entry coordinate. + /// + /// Used during insertion to calculate the actual distance needed to retract back to the entry coordinate. + private float _entryCoordinateDepth; + #endregion #region Public Functions @@ -130,7 +136,7 @@ public async Awaitable DriveToTargetEntryCoordinate() // Shortcut exit if error. if (CommunicationManager.HasError(firstMoveResponse.Error)) { - LogDriveToTargetEntryCoordinateProgress("Failed to move to DV position"); + LogDriveToTargetEntryCoordinateProgress("Failed to move to DV position."); return false; } @@ -142,7 +148,7 @@ public async Awaitable DriveToTargetEntryCoordinate() // Shortcut exit if error. if (CommunicationManager.HasError(secondMoveResponse.Error)) { - LogDriveToTargetEntryCoordinateProgress("Failed to move to AP position"); + LogDriveToTargetEntryCoordinateProgress("Failed to move to AP position."); return false; } @@ -154,12 +160,26 @@ public async Awaitable DriveToTargetEntryCoordinate() // Shortcut exit if error. if (CommunicationManager.HasError(thirdMoveResponse.Error)) { - LogDriveToTargetEntryCoordinateProgress("Failed to move to ML position"); + LogDriveToTargetEntryCoordinateProgress("Failed to move to ML position."); return false; } // Complete drive. + // Record depth at entry coordinate. + var entryCoordinatePositionResponse = await CommunicationManager.Instance.GetPosition( + ManipulatorID + ); + if (CommunicationManager.HasError(entryCoordinatePositionResponse.Error)) + { + LogDriveToTargetEntryCoordinateProgress( + "Failed to get final position at entry coordinate." + ); + return false; + } + + _entryCoordinateDepth = entryCoordinatePositionResponse.Position.w; + // Remove trajectory lines. RemoveTrajectoryLines(); @@ -208,7 +228,7 @@ ProbeManager targetInsertionProbeManager var entryCoordinateWorld = targetInsertionProbeManager.GetSurfaceCoordinateWorldT() - targetInsertionProbeManager.ProbeController.GetTipWorldU().tipForwardWorldU - * ENTRY_COORDINATE_DURA_DISTANCE; + * IDEAL_ENTRY_COORDINATE_TO_DURA_DISTANCE; // Convert world space to transformed space. var entryCoordinateAPMLDV = BrainAtlasManager.ActiveAtlasTransform.U2T( diff --git a/Assets/Scripts/UI/AutomationStack/AutomationStackHandler_Insertion.cs b/Assets/Scripts/UI/AutomationStack/AutomationStackHandler_Insertion.cs index cd50941d..d42b8cf3 100644 --- a/Assets/Scripts/UI/AutomationStack/AutomationStackHandler_Insertion.cs +++ b/Assets/Scripts/UI/AutomationStack/AutomationStackHandler_Insertion.cs @@ -25,7 +25,7 @@ private partial void OnDriveToTargetInsertionButtonPressed() ActiveManipulatorBehaviorController.Drive( _state.TargetInsertionProbeManager, _state.BaseSpeed, - _state.DrivePastTargetDistanceMillimeters / 1000f + _state.DrivePastTargetDistanceMillimeters ); } diff --git a/Assets/UI/Components/AutomationStack.uxml b/Assets/UI/Components/AutomationStack.uxml index b3273085..6bd9838a 100644 --- a/Assets/UI/Components/AutomationStack.uxml +++ b/Assets/UI/Components/AutomationStack.uxml @@ -84,6 +84,11 @@ + + + + + @@ -103,12 +108,6 @@ - - - - - -