Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drone #476

Closed
wants to merge 3 commits into from
Closed

Drone #476

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
9 changes: 9 additions & 0 deletions modular_robot/revolve2/aerial_robot/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
"""Classes and functions to describe and work with modular robots as used in the CI Group at VU Amsterdam."""

from ._aerial_robot import AerialRobot
from ._aerial_robot_control_interface import AerialRobotControlInterface

__all__ = [
"AerialRobot",
"AerialRobotControlInterface",
]
33 changes: 33 additions & 0 deletions modular_robot/revolve2/aerial_robot/_aerial_robot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import uuid

from .body.base import Body
from .brain import Brain


class AerialRobot:
"""A module robot consisting of a body and brain."""

_uuid: uuid.UUID

body: Body
brain: Brain

def __init__(self, body: Body, brain: Brain):
"""
Initialize this object.

:param body: The body of the modular robot.
:param brain: The brain of the modular robot.
"""
self._uuid = uuid.uuid1()
self.body = body
self.brain = brain

@property
def uuid(self) -> uuid.UUID:
"""
Get the uuid.

:returns: The uuid.
"""
return self._uuid
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from abc import ABC, abstractmethod

from .body.base import Motor


class AerialRobotControlInterface(ABC):
"""Interface for controlling aerial robots."""

@abstractmethod
def set_motor_target(self, motor: Motor, target: float) -> None:
"""
Set the position target for an active hinge.

:param active_hinge: The active hinge to set the target for.
:param target: The target to set.
"""
8 changes: 8 additions & 0 deletions modular_robot/revolve2/aerial_robot/body/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"""Modular robot bodies."""
from ._color import Color
from ._module import Module

__all__ = [
"Color",
"Module",
]
23 changes: 23 additions & 0 deletions modular_robot/revolve2/aerial_robot/body/_color.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from dataclasses import dataclass


@dataclass
class Color:
"""
Represents a color in RGBA format.

All values should from 0 to 255.
"""

red: int
green: int
blue: int
alpha: int

def to_normalized_rgba_list(self) -> list[float]:
"""
Convert to rgba list where each value is between 0 and 1.

:returns: The list.
"""
return [self.red / 255, self.green / 255, self.blue / 255, self.alpha / 255]
94 changes: 94 additions & 0 deletions modular_robot/revolve2/aerial_robot/body/_module.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
from __future__ import annotations

import uuid

from ._color import Color
import numpy as np

class Module:
"""Base class for a module for modular robots."""

def __init__(
self,
rotation: float,
color: Color,
) -> None:
"""
Initialize this object.

:param rotation: Orientation of this model relative to its parent.
:param color: The color of the module.
"""
self._uuid = uuid.uuid1()
self._connected_modules = []
self._rotation = rotation if isinstance(rotation, float) else rotation.value
self._color = color

@property
def uuid(self) -> uuid.UUID:
"""
Get the uuid.

:returns: The uuid.
"""
return self._uuid

@property
def rotation(self) -> float:
"""
Get the orientation of this model relative to its parent.

:returns: The orientation.
"""
return self._rotation

@property
def connected_modules(self) -> list[Module]:
"""
Get all children on this module.

:return: The children and their respective attachment point index.
"""
return self._connected_modules

def attach_module(self, module: Module) -> None:
"""
Attach a module to a slot.

:param module: The module to attach.
:param child_index: The slot to attach it to.
:raises KeyError: If attachment point is already populated.
"""
self._connected_modules.append(module)

def neighbours(self, depth: int = 1) -> list[Module]:
"""
Get the neighbours of this module with a certain range of the module tree.

:param depth: The range in which modules are considered a neighbour. Minimum is 1.
:returns: The neighbouring modules.
"""
assert(depth > 0)
neighbours: list[Module] = [self]
Q = [self]
current_depth = 0

while current_depth < depth and bool(Q):
newQ = np.array([])
for node in Q:
newQ = np.append(newQ, node.connected_modules)

neighbours = np.append(neighbours, newQ)
Q = newQ.copy()
current_depth += 1

return neighbours

@property
def color(self) -> Color:
"""
Get the color of this module.

:returns: The color.
"""
return self._color
10 changes: 10 additions & 0 deletions modular_robot/revolve2/aerial_robot/body/base/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
"""Base Modules for Robots."""
from ._motor import Motor
from ._motor_sensor import MotorSensor
from ._core import Core

__all__ = [
"Motor",
"MotorSensor",
"Core",
]
46 changes: 46 additions & 0 deletions modular_robot/revolve2/aerial_robot/body/base/_core.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import math

from pyrr import Quaternion, Vector3

from .._color import Color
from .._module import Module

class Core(Module):
"""The core module of a modular robot."""

def __init__(
self,
rotation: float,
mass: float,
bounding_box: Vector3,
):
"""
Initialize this object.

:param rotation: The Modules rotation.
:param mass: The Modules mass (in kg).
:param bounding_box: The bounding box. Vector3 with sizes of bbox in x,y,z dimension (m). Sizes are total length, not half length from origin.
"""
self._mass = mass
self._bounding_box = bounding_box

super().__init__(rotation, Color(255, 50, 50, 255))

@property
def mass(self) -> float:
"""
Get the mass of the Core (in kg).

:return: The value.
"""
return self._mass

@property
def bounding_box(self) -> Vector3:
"""
Get the bounding box.

Sizes are total length, not half length from origin.
:return: Vector3 with sizes of bbox in x,y,z dimension (m).
"""
return self._bounding_box
Loading
Loading