Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions srv/ToggleAlignment.srv
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
bool enable
---
bool success
16 changes: 15 additions & 1 deletion teleoperation/basestation_gui/backend/ws/auton_ws.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import asyncio
from backend.ws.base_ws import WebSocketHandler
from backend.managers.ros import get_logger
from backend.managers.ros import get_logger, get_service_client
from backend.utils.ros_service import call_service_async
from rclpy.action import ActionClient
from mrover.action import TypingCode
from mrover.msg import KeyboardYaw
from mrover.srv import ToggleAlignment


class AutonHandler(WebSocketHandler):
Expand All @@ -24,6 +26,8 @@ async def handle_message(self, data):
await self.cancel_goal()
else:
await self.send_typing_code(code)
elif msg_type == 'toggle_alignment':
await self.toggle_alignment(data.get('enable', False))
else:
get_logger().warning(f"Unhandled AUTON message: {msg_type}")

Expand Down Expand Up @@ -60,6 +64,16 @@ def feedback_callback(self, feedback_msg):
'current_index': feedback.current_index,
})

async def toggle_alignment(self, enable: bool):
client = get_service_client(ToggleAlignment, '/toggle_alignment')
request = ToggleAlignment.Request()
request.enable = enable
result, error = await call_service_async(client, request)
if error:
self.schedule_send({'type': 'alignment_error', 'error': error})
else:
self.schedule_send({'type': 'alignment_toggled', 'enable': enable, 'success': result.success})

async def cancel_goal(self):
if self.current_goal_handle:
await asyncio.to_thread(self.current_goal_handle.cancel_goal_async)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,15 @@
<span class="spacer"></span>
<span class="yaw-label">YAW</span>
<span class="data-value">{{ yawAngle.toFixed(3) }}</span><span class="data-unit">rad</span>
<button
class="btn btn-sm"
:class="alignmentEnabled ? 'btn-success' : 'btn-danger'"
data-testid="pw-alignment-toggle"
:disabled="codeSent"
@click.prevent="toggleAlignment()"
>
Align {{ alignmentEnabled ? 'ON' : 'OFF' }}
</button>
</div>
<table class="feedback-table" data-testid="pw-typing-feedback">
<tbody>
Expand All @@ -49,6 +58,7 @@
<script lang="ts" setup>
import { ref, onMounted, onBeforeUnmount } from 'vue'
import { useWebsocketStore } from '@/stores/websocket'
import { useNotificationsStore } from '@/stores/notifications'

interface TypingFeedbackMessage {
type: 'typing_feedback'
Expand All @@ -65,14 +75,21 @@ interface KeyboardYawMessage {
yaw: number
}

interface AlignmentErrorMessage {
type: 'alignment_error'
error: string
}

const websocketStore = useWebsocketStore()
const notificationsStore = useNotificationsStore()

const typingMessage = ref('')
const codeSent = ref(false)
const currentIndex = ref(0)
const currentState = ref('')
const letterStates = ref<string[]>(Array(6).fill('notTyped'))
const yawAngle = ref(0)
const alignmentEnabled = ref(true)

onMounted(() => {
websocketStore.setupWebSocket('auton')
Expand Down Expand Up @@ -101,12 +118,30 @@ websocketStore.onMessage<KeyboardYawMessage>('auton', 'keyboard_yaw', (msg) => {
yawAngle.value = msg.yaw
})

websocketStore.onMessage<AlignmentErrorMessage>('auton', 'alignment_error', (msg) => {
alignmentEnabled.value = !alignmentEnabled.value
notificationsStore.addNotification({
component: 'Alignment',
message: msg.error,
fullData: msg,
})
})

websocketStore.onMessage<TypingCancelledMessage>('auton', 'typing_cancelled', () => {
codeSent.value = false
typingMessage.value = ''
letterStates.value = Array(6).fill('notTyped')
})

function toggleAlignment() {
const nextState = !alignmentEnabled.value
websocketStore.sendMessage('auton', {
type: 'toggle_alignment',
enable: nextState,
})
alignmentEnabled.value = nextState
}

function submitMessage() {
if (!codeSent.value) {
websocketStore.sendMessage('auton', {
Expand Down
Loading