Skip to content
Merged
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
31 changes: 31 additions & 0 deletions dimos/mapping/spec.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Copyright 2025 Dimensional Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from typing import Protocol

from dimos.core import Out
from dimos.msgs.nav_msgs import OccupancyGrid
from dimos.msgs.sensor_msgs import PointCloud2


class Global3DMapSpec(Protocol):
global_pointcloud: Out[PointCloud2]


class GlobalMapSpec(Protocol):
global_map: Out[OccupancyGrid]


class GlobalCostmapSpec(Protocol):
global_costmap: Out[OccupancyGrid]
39 changes: 39 additions & 0 deletions dimos/navigation/rosnav.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Copyright 2025 Dimensional Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from dimos.core import In, Module, Out
from dimos.msgs.geometry_msgs import PoseStamped, Twist
from dimos.msgs.nav_msgs import Path
from dimos.msgs.sensor_msgs import PointCloud2


class ROSNav(Module):
goal_req: In[PoseStamped] = None # type: ignore
goal_active: Out[PoseStamped] = None # type: ignore
path_active: Out[Path] = None # type: ignore
ctrl: Out[Twist] = None # type: ignore

# PointcloudPerception attributes
pointcloud: Out[PointCloud2] = None # type: ignore

# Global3DMapSpec attributes
global_pointcloud: Out[PointCloud2] = None # type: ignore

def navigate_to_target(self, target: PoseStamped) -> None:
# TODO: Implement navigation logic
pass

def stop_navigating(self) -> None:
# TODO: Implement stop logic
pass
31 changes: 31 additions & 0 deletions dimos/navigation/spec.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Copyright 2025 Dimensional Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from typing import Protocol

from dimos.core import In, Out
from dimos.msgs.geometry_msgs import PoseStamped, Twist
from dimos.msgs.nav_msgs import Path


class NavSpec(Protocol):
goal_req: In[PoseStamped]
goal_active: Out[PoseStamped]
path_active: Out[Path]
ctrl: Out[Twist]

# identity quaternion (Quaternion(0,0,0,1)) represents "no rotation requested"
def navigate_to_target(self, target: PoseStamped) -> None: ...

def stop_navigating(self) -> None: ...
37 changes: 37 additions & 0 deletions dimos/navigation/test_rosnav.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Copyright 2025 Dimensional Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from typing import Protocol

from dimos.mapping.spec import Global3DMapSpec
from dimos.navigation.rosnav import ROSNav
from dimos.navigation.spec import NavSpec
from dimos.perception.spec import PointcloudPerception


class RosNavSpec(NavSpec, PointcloudPerception, Global3DMapSpec, Protocol):
"""Combined protocol for navigation components."""

pass


def accepts_combined_protocol(nav: RosNavSpec) -> None:
"""Function that accepts all navigation protocols at once."""
pass


def test_typing_prototypes():
"""Test that ROSNav correctly implements all required protocols."""
rosnav = ROSNav()
accepts_combined_protocol(rosnav)
22 changes: 22 additions & 0 deletions dimos/perception/spec.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Copyright 2025 Dimensional Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from typing import Protocol

from dimos.core import Out
from dimos.msgs.sensor_msgs import PointCloud2


class PointcloudPerception(Protocol):
pointcloud: Out[PointCloud2]
Loading