Skip to content

Commit

Permalink
Mission-planning: Add scan direction modifier to existent surveys
Browse files Browse the repository at this point in the history
Signed-off-by: Arturo Manzoli <[email protected]>
  • Loading branch information
ArturoManzoli committed Jan 14, 2025
1 parent d0f5a91 commit 452dd23
Show file tree
Hide file tree
Showing 4 changed files with 243 additions and 13 deletions.
155 changes: 153 additions & 2 deletions src/components/mission-planning/ContextMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,61 @@
:style="{ top: `${position.y}px`, left: `${position.x}px` }"
class="context-menu absolute flex justify-center items-center z-[1000] text-white rounded-lg w-auto h-auto"
>
<div v-if="selectedSurveyId" class="relative orbit-container">
<div class="central-element flex justify-start items-start">
<ScanDirectionDial :angle="angle" auto-update :polygon-state="false" />
</div>

<div id="button-1" class="orbit-button orbit-button-1">
<v-tooltip :text="isFirstWaypoints ? 'Create survey' : 'Add survey'">
<template #activator="{ props: tooltipProps0 }">
<v-btn
v-bind="tooltipProps0"
:style="[interfaceStore.globalGlassMenuStyles, { backgroundColor: '#333333EE' }]"
variant="elevated"
icon="mdi-transit-connection-variant"
rounded="full"
size="x-small"
color="#FFFFFF22"
class="text-[12px] rotate-[145deg]"
@click="handleToggleSurvey"
></v-btn
></template>
</v-tooltip>
</div>

<div id="button-2" class="orbit-button orbit-button-2">
<v-tooltip :text="isFirstWaypoints ? 'Create simple path' : 'Add simple path'">
<template #activator="{ props: tooltipProps1 }">
<v-btn
v-bind="tooltipProps1"
:style="[interfaceStore.globalGlassMenuStyles, { backgroundColor: '#333333EE' }]"
variant="elevated"
icon="mdi-vector-polyline"
rounded="full"
size="x-small"
color="#FFFFFF22"
class="text-[13px] rotate-[170deg]"
@click="handleToggleSimpleMission"
></v-btn>
</template>
</v-tooltip>
</div>
<v-tooltip text="Delete survey">
<template #activator="{ props: tooltipProps3 }">
<div
v-bind="tooltipProps3"
class="absolute text-[14px] mt-[10px] ml-[85px] bg-transparent rounded-full cursor-pointer elevation-4"
variant="text"
@click="handleDeleteSelectedSurvey"
>
<v-icon color="white" class="border-2 rounded-full bg-red">mdi-close</v-icon>
</div>
</template>
</v-tooltip>
</div>
<div
v-else
class="flex flex-col rounded-md"
:style="[interfaceStore.globalGlassMenuStyles, { background: '#333333EE', border: '1px solid #FFFFFF44' }]"
>
Expand Down Expand Up @@ -38,8 +92,10 @@
<script setup lang="ts">
import { computed, defineEmits, defineProps } from 'vue'
import ScanDirectionDial from '@/components/mission-planning/ScanDirectionDial.vue'
import { useAppInterfaceStore } from '@/stores/appInterface'
import { useMissionStore } from '@/stores/mission'
import { Survey } from '@/types/mission'
const missionStore = useMissionStore()
const interfaceStore = useAppInterfaceStore()
Expand All @@ -51,6 +107,8 @@ const props = defineProps<{
x: number
y: number
}
surveys: Survey[]
selectedSurveyId: string | null
isCreatingSurvey: boolean
isCreatingSimpleMission: boolean
}>()
Expand All @@ -60,13 +118,22 @@ const emit = defineEmits<{
(event: 'close'): void
(event: 'toggleSurvey'): void
(event: 'toggleSimpleMission'): void
(event: 'deleteSelectedSurvey'): void
}>()
const selectedSurveyId = computed(() => props.selectedSurveyId)
const angle = computed(() => props.surveys.find((survey) => survey.id === props.selectedSurveyId)?.surveyLinesAngle)
const isFirstWaypoints = computed(
() => props.surveys.length === 0 && missionStore.currentPlanningWaypoints.length === 0
)
const surveyCreationButtonText = computed(() => {
if (props.isCreatingSurvey) {
return 'Close survey creation'
}
if (missionStore.currentPlanningWaypoints.length > 0) {
if (props.surveys.length === 0) {
return 'Create survey'
}
return 'Add survey'
Expand All @@ -76,7 +143,7 @@ const pathCreationButtonText = computed(() => {
if (props.isCreatingSimpleMission) {
return 'Close simple path creation'
}
if (missionStore.currentPlanningWaypoints.length > 0) {
if (props.surveys.length === 0) {
return 'Create simple path'
}
return 'Add simple path'
Expand All @@ -91,11 +158,95 @@ const handleToggleSimpleMission = (): void => {
emit('toggleSimpleMission')
emit('close')
}
const handleDeleteSelectedSurvey = (): void => {
emit('deleteSelectedSurvey')
}
</script>

<style scoped>
.context-menu {
transform-origin: center;
opacity: 0;
animation: bloom 0.3s ease-out forwards;
}
@keyframes bloom {
0% {
transform: scale(0.15);
opacity: 0;
}
100% {
transform: scale(1);
opacity: 1;
}
}
.orbit-container {
position: relative;
width: 80px;
height: 80px;
}
.central-element {
position: relative;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.orbit-button {
position: absolute;
top: 50%;
left: 50%;
transform-origin: center;
opacity: 0;
}
.orbit-button-1 {
animation: orbit-1 0.5s ease-out forwards;
}
.orbit-button-2 {
animation: orbit-2 0.4s ease-out forwards;
animation-delay: 0.2s;
}
.orbit-button-3 {
animation: orbit-3 0.3s ease-out forwards;
animation-delay: 0.4s;
}
@keyframes orbit-1 {
0% {
transform: translate(-50%, -50%) rotate(0deg) translateX(0);
opacity: 0;
}
100% {
transform: translate(-50%, -50%) rotate(-500deg) translateX(90px);
opacity: 1;
}
}
@keyframes orbit-2 {
0% {
transform: translate(-50%, -50%) rotate(0deg) translateX(0);
opacity: 0;
}
100% {
transform: translate(-50%, -50%) rotate(-541deg) translateX(90px);
opacity: 1;
}
}
@keyframes orbit-3 {
0% {
transform: translate(-50%, -50%) rotate(0deg) translateX(0);
opacity: 0;
}
100% {
transform: translate(-50%, -50%) rotate(-580deg) translateX(90px);
opacity: 1;
}
}
</style>
14 changes: 7 additions & 7 deletions src/components/mission-planning/ScanDirectionDial.vue
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,9 @@
<script setup lang="ts">
import { inject, onUnmounted, ref, watch } from 'vue'
import { useAppInterfaceStore } from '@/stores/appInterface'
const interfaceStore = useAppInterfaceStore()
/* eslint-disable jsdoc/require-jsdoc */
const props = defineProps<{
autoUpdate?: boolean
angle: number | undefined
polygonState: boolean
}>()
Expand All @@ -53,16 +50,19 @@ watch(
}
)
const regenerateSurveyWaypoints = inject<(angle?: number) => void>('regenerateSurveyWaypoints')
const surveyLinesAngle = inject<(angle: number) => void>('surveyLinesAngle')
const updateLinesAngleOnParent = (): void => {
if (props.autoUpdate && regenerateSurveyWaypoints && !polygonStateEdit.value) {
regenerateSurveyWaypoints(rotationAngle.value)
}
if (polygonStateEdit.value && surveyLinesAngle) {
surveyLinesAngle(rotationAngle.value || 0)
}
}
const startDrag = (event: MouseEvent): void => {
interfaceStore.configPanelVisible = false
hovering.value = true
event.preventDefault()
const target = event.currentTarget as HTMLElement
Expand Down Expand Up @@ -112,7 +112,7 @@ const getCardinalDirection = (angle: number): string => {
'N',
]
const normalizedAngle = ((angle % 360) + 360) % 360
const index = Math.round(normalizedAngle / 22.5)
const index = Math.round(normalizedAngle / 22.5) // 22.5 comes from 360 divided by 16, that results on the cardinal directions positions
return directions[index]
}
Expand All @@ -125,7 +125,7 @@ onUnmounted(() => {

<style scoped>
.overlay {
z-index: 1100;
z-index: 100;
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
}
Expand Down
2 changes: 1 addition & 1 deletion src/libs/utils-map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ export const generateSurveyPath = (
const [minX, minY, maxX, maxY] = bbox
const diagonal = Math.sqrt(Math.pow(maxX - minX, 2) + Math.pow(maxY - minY, 2))

const adjustedAngle = linesAngle
const adjustedAngle = linesAngle + 90
const angleRad = (adjustedAngle * Math.PI) / 180

const continuousPath: L.LatLng[] = []
Expand Down
Loading

0 comments on commit 452dd23

Please sign in to comment.