Skip to content

Commit

Permalink
Merge pull request #52 from LUXROBO/feature/fix-property-manager-issue46
Browse files Browse the repository at this point in the history
Feature/fix property manager issue46
  • Loading branch information
boobooboo2 authored Jan 19, 2023
2 parents aea1531 + d78ad81 commit 64e2d4e
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 29 deletions.
88 changes: 64 additions & 24 deletions modi_plus/module/module.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,14 @@ def __init__(self, id_, uuid, connection_task):
self._id = id_
self._uuid = uuid
self._connection = connection_task

self.module_type = str()
self._properties = dict()

# sampling_rate = (100 - property_sampling_frequency) * 11, in ms
self.prop_samp_freq = 91
# property
self.prop_samp_freq = 91 # sampling_rate[ms] = (100 - property_sampling_frequency) * 11
self.prop_request_period = 2 # [s]
self.__get_properties = dict()
self.__set_properties = dict()
self.__last_set_property_num = None

self.is_connected = True
self.is_usb_connected = False
Expand Down Expand Up @@ -213,32 +215,33 @@ def _get_property(self, property_type: int) -> bytearray:
"""

# Register property if not exists
if property_type not in self._properties:
self._properties[property_type] = self.Property()
if property_type not in self.__get_properties:
self.__get_properties[property_type] = self.Property()
self.__request_property(self._id, property_type)

# Request property value if not updated for 1.5 sec
last_update = self._properties[property_type].last_update_time
if time.time() - last_update > 1.5:
# Request property value if not updated for 2 sec
last_update = self.__get_properties[property_type].last_update_time
if time.time() - last_update > self.prop_request_period:
self.__request_property(self._id, property_type)

if self._properties[property_type].value is None:
if self.__get_properties[property_type].value is None:
if self._enable_get_property_timeout:
first_request_time = time.time()

# 3s timeout
while self._properties[property_type].value is None:
while self.__get_properties[property_type].value is None:
if time.time() - first_request_time > 3:
raise Module.GetValueInitTimeout
time.sleep(0.1)
else:
return bytearray(12)

return self._properties[property_type].value
return self.__get_properties[property_type].value

def _set_property(self, destination_id: int,
property_num: int,
property_values: Union[Tuple, str]) -> None:
property_values: Union[Tuple, str],
force: bool = False) -> None:
"""Send the message of set_property command to the module
:param destination_id: Id of the destination module
Expand All @@ -247,15 +250,46 @@ def _set_property(self, destination_id: int,
:type property_num: int
:param property_values: Property Values
:type property_values: Tuple
:param force: Force data to be sent
:type force: bool
:return: None
"""

message = parse_set_property_message(
destination_id,
property_num,
property_values,
)
self._connection.send(message)
do_send = False
now_time = time.time()

if not self.__check_last_set_property(property_num):
force = True

if property_num in self.__set_properties:
if property_values == self.__set_properties[property_num].value:
duration = now_time - self.__set_properties[property_num].last_update_time
if force or duration > self.prop_request_period:
# 마지막으로 보낸 데이터와 같은 경우, 2초마다 전송 or force가 true인 경우
self.__set_properties[property_num].value = property_values
self.__set_properties[property_num].last_update_time = now_time
do_send = True
else:
# 마지막으로 보낸 데이터와 다른 경우, 바로 전송
self.__set_properties[property_num].value = property_values
self.__set_properties[property_num].last_update_time = now_time
do_send = True
else:
# 데이터를 한번도 안 보낸 경우, 바로 전송
self.__set_properties[property_num] = self.Property()
self.__set_properties[property_num].value = property_values
self.__set_properties[property_num].last_update_time = now_time
do_send = True

if do_send:
message = parse_set_property_message(
destination_id,
property_num,
property_values,
)
self._connection.send_nowait(message)

self.__last_set_property_num = property_num

def update_property(self, property_type: int, property_value: bytearray) -> None:
""" Update property value and time
Expand All @@ -266,10 +300,10 @@ def update_property(self, property_type: int, property_value: bytearray) -> None
:type property_value: bytearray
"""

if property_type not in self._properties:
self._properties[property_type] = self.Property()
self._properties[property_type].value = property_value
self._properties[property_type].last_update_time = time.time()
if property_type not in self.__get_properties:
self.__get_properties[property_type] = self.Property()
self.__get_properties[property_type].value = property_value
self.__get_properties[property_type].last_update_time = time.time()

def __request_property(self, destination_id: int, property_type: int) -> None:
""" Generate message for request property
Expand All @@ -281,10 +315,16 @@ def __request_property(self, destination_id: int, property_type: int) -> None:
:return: None
"""

self._properties[property_type].last_update_time = time.time()
self.__get_properties[property_type].last_update_time = time.time()
req_prop_msg = parse_get_property_message(destination_id, property_type, self.prop_samp_freq)
self._connection.send(req_prop_msg)

def __check_last_set_property(self, property_num: int) -> bool:
if self.__last_set_property_num is None:
return False
else:
return self.__last_set_property_num == property_num


class SetupModule(Module):
pass
Expand Down
14 changes: 12 additions & 2 deletions modi_plus/module/output_module/display.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Display module."""

import time
from typing import List
from modi_plus.module.module import OutputModule

Expand Down Expand Up @@ -208,10 +209,12 @@ def write_text(self, text: str) -> None:
self._set_property(
self._id,
Display.PROPERTY_DISPLAY_WRITE_TEXT,
property_values=(("bytes", data), )
property_values=(("bytes", data), ),
force=True
)

self._text = text
time.sleep(0.02 + 0.003 * len(encoding_data))

def write_variable(self, x: int, y: int, variable: float) -> None:
"""Show the input variable on the display.
Expand All @@ -233,6 +236,7 @@ def write_variable(self, x: int, y: int, variable: float) -> None:
("float", variable), )
)
self._text += str(variable)
time.sleep(0.01)

def draw_picture(self, x: int, y: int, name: int) -> None:
"""Clears the display and show the input picture on the display.
Expand All @@ -259,6 +263,7 @@ def draw_picture(self, x: int, y: int, name: int) -> None:
("u8", Display.HEIGHT),
("string", file_name), )
)
time.sleep(0.05)

def draw_dot(self, dot: bytes) -> None:
"""Clears the display and show the input dot on the display.
Expand All @@ -284,6 +289,7 @@ def draw_dot(self, dot: bytes) -> None:
Display.PROPERTY_DISPLAY_DRAW_DOT,
property_values=(("bytes", send_data), )
)
time.sleep(0.3)

def set_offset(self, x: int, y: int) -> None:
"""Set origin point on the screen
Expand All @@ -300,6 +306,7 @@ def set_offset(self, x: int, y: int) -> None:
Display.PROPERTY_DISPLAY_SET_OFFSET,
property_values=(("s8", x), ("s8", y), )
)
time.sleep(0.01)

def move_screen(self, x: int, y: int) -> None:
"""Move the screen by x and y
Expand All @@ -314,8 +321,10 @@ def move_screen(self, x: int, y: int) -> None:
self._set_property(
self.id,
Display.PROPERTY_DISPLAY_MOVE_SCREEN,
property_values=(("s8", x), ("s8", y), )
property_values=(("s8", x), ("s8", y), ),
force=True
)
time.sleep(0.01)

def reset(self) -> None:
"""Clear the screen.
Expand All @@ -329,3 +338,4 @@ def reset(self) -> None:
property_values=(("u8", 0), )
)
self._text = ""
time.sleep(0.01)
8 changes: 7 additions & 1 deletion modi_plus/module/output_module/motor.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Motor module."""

import time
import struct
from typing import Tuple
from modi_plus.module.module import OutputModule
Expand Down Expand Up @@ -109,6 +110,7 @@ def set_angle(self, target_angle: int, target_speed: int = 70) -> None:
property_values=(("u16", target_angle),
("u16", target_speed), )
)
time.sleep(0.01)

def set_speed(self, target_speed: int) -> None:
"""Sets the speed of the motor
Expand All @@ -123,6 +125,7 @@ def set_speed(self, target_speed: int) -> None:
property_num=Motor.PROPERTY_MOTOR_SPEED,
property_values=(("s32", target_speed), )
)
time.sleep(0.01)

def append_angle(self, target_angle: int, target_speed: int = 70) -> None:
"""append the angle form current angle of the motor
Expand All @@ -138,8 +141,10 @@ def append_angle(self, target_angle: int, target_speed: int = 70) -> None:
destination_id=self._id,
property_num=Motor.PROPERTY_MOTOR_ANGLE_APPEND,
property_values=(("s16", target_angle),
("u16", target_speed), )
("u16", target_speed), ),
force=True
)
time.sleep(0.01)

def stop(self) -> None:
"""Stop operating motor
Expand All @@ -152,3 +157,4 @@ def stop(self) -> None:
property_num=Motor.PROPERTY_MOTOR_STOP,
property_values=()
)
time.sleep(0.01)
3 changes: 3 additions & 0 deletions modi_plus/module/output_module/speaker.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Speaker module."""

import time
import struct
from typing import List, Tuple, Union
from modi_plus.module.module import OutputModule
Expand Down Expand Up @@ -216,6 +217,7 @@ def set_tune(self, frequency: Union[int, str], volume: int) -> None:
property_num=Speaker.PROPERTY_SPEAKER_SET_TUNE,
property_values=(("u16", frequency), ("u16", volume), )
)
time.sleep(0.01)

def play_music(self, name: str, volume: int) -> None:
"""Play music in speaker module
Expand All @@ -241,6 +243,7 @@ def play_music(self, name: str, volume: int) -> None:
("u8", volume),
("string", self.playing_file_name), )
)
time.sleep(0.1)

def stop_music(self) -> None:
"""Stop music in speaker module
Expand Down
6 changes: 4 additions & 2 deletions modi_plus/module/setup_module/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,8 @@ def send_data(self, index: int, data: int) -> None:
self._set_property(
destination_id=self._id,
property_num=property_num,
property_values=(("s32", data),)
property_values=(("s32", data),),
force=True
)

@check_connection
Expand All @@ -345,7 +346,8 @@ def send_text(self, text: str) -> None:
self._set_property(
destination_id=self._id,
property_num=Network.PROPERTY_NETWORK_SEND_TEXT,
property_values=(("string", text),)
property_values=(("string", text),),
force=True
)

@check_connection
Expand Down
3 changes: 3 additions & 0 deletions modi_plus/util/unittest_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ def __init__(self):
def send(self, pkt):
self.send_list.append(pkt)

def send_nowait(self, pkt):
self.send_list.append(pkt)

def recv(self):
return "Test"

Expand Down

0 comments on commit 64e2d4e

Please sign in to comment.