-
Notifications
You must be signed in to change notification settings - Fork 32
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
WIP: Added TX branching measurement #106
base: task_morphology
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,11 +24,23 @@ def grams(x): | |
|
||
# Module Orientation | ||
class Orientation(Enum): | ||
BACK = 0 | ||
BACK = 0 # This is the parent attachment point (if any) | ||
FORWARD = 1 | ||
RIGHT = 2 | ||
LEFT = 3 | ||
|
||
def opposite(self): | ||
if self == self.BACK: | ||
return self.FORWARD | ||
elif self == self.FORWARD: | ||
return self.BACK | ||
elif self == self.RIGHT: | ||
return self.LEFT | ||
elif self == self.LEFT: | ||
return self.RIGHT | ||
else: | ||
assert False | ||
|
||
def short_repr(self): | ||
if self == self.BACK: | ||
return 'B' | ||
|
@@ -222,20 +234,66 @@ def possible_slots(self): | |
(box_geometry[2] / -2.0, box_geometry[2] / 2.0), # Z | ||
) | ||
|
||
def has_children(self): | ||
def has_children(self) -> bool: | ||
""" | ||
Check wheter module has children | ||
Check whether module has children | ||
:return: True if module has children | ||
""" | ||
has_children = False | ||
for i, child in self.iter_children(): | ||
if child is not None: | ||
return True | ||
return False | ||
|
||
if self.children == {1: None}: return False | ||
def count_module_connections(self) -> int: | ||
""" | ||
Count how many connections the module has. | ||
Connected TouchSensor and BrickSensor Modules are ignored | ||
:return: number of connections | ||
""" | ||
if not self.has_children(): | ||
return 1 | ||
|
||
for i, child in enumerate(self.children): | ||
children_count = 0 | ||
for core_slot, child in self.iter_children(): | ||
if child is not None: | ||
has_children = True | ||
continue | ||
if not isinstance(child, TouchSensorModule) and \ | ||
not isinstance(child, BrickSensorModule): | ||
children_count += 1 | ||
|
||
return has_children | ||
return children_count + 1 | ||
|
||
def is_folding(self) -> bool: | ||
""" | ||
Checks if the module is a folding point. | ||
The module is a folding point if and only if it has one child and that child is not | ||
attached opposite to the parent. | ||
:return: True if the module is a folding point | ||
""" | ||
if not self.has_children(): | ||
return False | ||
|
||
# Default parent slot is BACK | ||
parent_slot = Orientation.BACK | ||
|
||
target_slot = None | ||
for slot, child in self.iter_children(): | ||
if slot == parent_slot: | ||
continue | ||
# is the child slot occupied? | ||
if child is None: | ||
continue | ||
# ignore TouchSensor and BrickSensor modules | ||
if isinstance(child, TouchSensorModule) or \ | ||
isinstance(child, BrickSensorModule): | ||
continue | ||
# second slot found, not a fold | ||
if target_slot is not None: | ||
return False | ||
target_slot = slot | ||
|
||
target_slot = Orientation(target_slot) | ||
return parent_slot.opposite() != target_slot | ||
|
||
|
||
class CoreModule(RevolveModule): | ||
|
@@ -265,6 +323,38 @@ def to_sdf(self, tree_depth='', parent_link=None, child_link=None): | |
parent_link.append(imu_sensor) | ||
return visual, collision, imu_sensor | ||
|
||
def count_module_connections(self) -> int: | ||
""" | ||
Count how many connections the module has. | ||
Connected TouchSensor and BrickSensor Modules are ignored | ||
:return: number of connections | ||
""" | ||
# The CoreModule does not have a parent module | ||
return super(CoreModule, self).count_module_connections() - 1 | ||
|
||
def is_folding(self) -> bool: | ||
# parent slot is not supposed to be set | ||
parent_slot = None | ||
target_slot = None | ||
for slot, child in self.iter_children(): | ||
# is the child slot occupied? | ||
if child is None: | ||
continue | ||
# ignore TouchSensor and BrickSensor modules | ||
if isinstance(child, TouchSensorModule) or \ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You could inherit TouchSensorModule from SensorModule (create new class) and inherit BrickSensorModule from SensorModule so you only have to do one check instead of two. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah, good point. But I'm not going to touch that right now. It's out of scope and I'm afraid I'm going to break stuff There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could literaly do class SensorModule: class TouchSensorModule(SensorModule): class BrickSensorModule(SensorModule): But yeah, that is up to you. |
||
isinstance(child, BrickSensorModule): | ||
continue | ||
if parent_slot is None: | ||
parent_slot = slot | ||
elif target_slot is None: | ||
target_slot = slot | ||
else: | ||
# More than 2 children, this is not a fold | ||
return False | ||
if parent_slot is None or target_slot is None: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will always trigger when only the parent_slot is filled in the first iteration that a viable child is set as the parent_slot at line 348. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What do you mean? This if will trigger if I've found both a first and a second child, at least that was my intention. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's say we are in the first iteration of this for loop and it found a viable child and we are saving the slot of this child at line 348. Then now we come to 354 and we say that this statement is true, since the target slot is still unfilled, then we return false, I do not think this is expected behavior. |
||
return False | ||
return parent_slot.opposite() != target_slot | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will only trigger after executing line 350 is executed, but this does not necessarily need to be opposite right? After that it cannot be changed since you already return that it is False. |
||
|
||
|
||
class ActiveHingeModule(RevolveModule): | ||
""" | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -81,6 +81,7 @@ def test_measurements_body(self): | |
connectivity2_abs = 4 | ||
connectivity3 = 1 | ||
connectivity4 = 1 | ||
connectivity5 = 1 | ||
coverage = 0.44 | ||
effective_joints = 0.444 | ||
joints_abs = 6 | ||
|
@@ -101,6 +102,7 @@ def test_measurements_body(self): | |
self.assertAlmostEqual(connectivity2_abs, m.extensiveness, 3) | ||
# self.assertAlmostEqual(connectivity3, m., 3) | ||
self.assertAlmostEqual(connectivity4, m.branching_modules_count, 3) | ||
self.assertAlmostEqual(connectivity5, m.tx_branching_modules_count, 3) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why not assertEqual? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. because these are floating point values There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is a counter a floating point value, can you count half branching modules? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. good point, this is an integer counter :/ |
||
self.assertAlmostEqual(coverage, m.coverage, 3) | ||
self.assertAlmostEqual(effective_joints, m.joints, 3) | ||
self.assertAlmostEqual(joints_abs, m.hinge_count, 3) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does is_folding need to be overwritten by CoreModule?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because in the other function I assume you always have one connection already, which is the connection to the parent. In this case the assumption is broken.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there anything we can reuse?