Skip to content

Commit 8c61299

Browse files
author
Chris Elion
committed
SideChannel helper messages
1 parent 788a347 commit 8c61299

File tree

10 files changed

+112
-62
lines changed

10 files changed

+112
-62
lines changed

DevProject/ProjectSettings/ProjectSettings.asset

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ PlayerSettings:
103103
xboxOneMonoLoggingLevel: 0
104104
xboxOneLoggingLevel: 1
105105
xboxOneDisableEsram: 0
106+
xboxOneEnableTypeOptimization: 0
106107
xboxOnePresentImmediateThreshold: 0
107108
switchQueueCommandMemory: 1048576
108109
switchQueueControlMemory: 16384
@@ -157,7 +158,7 @@ PlayerSettings:
157158
useHDRDisplay: 0
158159
D3DHDRBitDepth: 0
159160
m_ColorGamuts: 00000000
160-
targetPixelDensity: 0
161+
targetPixelDensity: 30
161162
resolutionScalingMode: 0
162163
androidSupportedAspectRatio: 1
163164
androidMaxAspectRatio: 2.1
@@ -179,10 +180,10 @@ PlayerSettings:
179180
StripUnusedMeshComponents: 0
180181
VertexChannelCompressionMask: 4054
181182
iPhoneSdkVersion: 988
182-
iOSTargetOSVersionString:
183+
iOSTargetOSVersionString: 10.0
183184
tvOSSdkVersion: 0
184185
tvOSRequireExtendedGameController: 0
185-
tvOSTargetOSVersionString:
186+
tvOSTargetOSVersionString: 10.0
186187
uIPrerenderedIcon: 0
187188
uIRequiresPersistentWiFi: 0
188189
uIRequiresFullScreen: 1
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
m_EditorVersion: 2018.4.14f1
1+
m_EditorVersion: 2018.4.17f1

com.unity.ml-agents/Runtime/Agent.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -583,7 +583,6 @@ void SendInfoToBrain()
583583
{
584584
throw new UnityAgentsException("Call to SendInfoToBrain when Agent hasn't been initialized." +
585585
"Please ensure that you are calling 'base.OnEnable()' if you have overridden OnEnable.");
586-
587586
}
588587

589588
if (m_Brain == null)

com.unity.ml-agents/Tests/Editor/MLAgentsEditModeTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ internal void SetPolicy(IPolicy policy)
3838

3939
internal IPolicy GetPolicy()
4040
{
41-
return (IPolicy) typeof(Agent).GetField("m_Brain", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(this);
41+
return (IPolicy)typeof(Agent).GetField("m_Brain", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(this);
4242
}
4343

4444
public int initializeAgentCalls;

ml-agents-envs/mlagents_envs/environment.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from typing import Dict, List, Optional, Any
99

1010
import mlagents_envs
11-
from mlagents_envs.side_channel.side_channel import SideChannel
11+
from mlagents_envs.side_channel.side_channel import SideChannel, IncomingMessage
1212

1313
from mlagents_envs.base_env import (
1414
BaseEnv,
@@ -498,7 +498,8 @@ def _parse_side_channel_message(
498498
"sending side channel data properly.".format(channel_id)
499499
)
500500
if channel_id in side_channels:
501-
side_channels[channel_id].on_message_received(message_data)
501+
incoming_message = IncomingMessage(message_data)
502+
side_channels[channel_id].on_message_received(incoming_message)
502503
else:
503504
logger.warning(
504505
"Unknown side channel data received. Channel type "

ml-agents-envs/mlagents_envs/side_channel/engine_configuration_channel.py

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
from mlagents_envs.side_channel.side_channel import SideChannel
1+
from mlagents_envs.side_channel.side_channel import (
2+
SideChannel,
3+
OutgoingMessage,
4+
IncomingMessage,
5+
)
26
from mlagents_envs.exception import UnityCommunicationException
3-
import struct
47
import uuid
58
from typing import NamedTuple
69

@@ -31,7 +34,7 @@ class EngineConfigurationChannel(SideChannel):
3134
def __init__(self) -> None:
3235
super().__init__(uuid.UUID("e951342c-4f7e-11ea-b238-784f4387d1f7"))
3336

34-
def on_message_received(self, data: bytes) -> None:
37+
def on_message_received(self, msg: IncomingMessage) -> None:
3538
"""
3639
Is called by the environment to the side channel. Can be called
3740
multiple times per step if multiple messages are meant for that
@@ -65,18 +68,16 @@ def set_configuration_parameters(
6568
:param target_frame_rate: Instructs simulation to try to render at a
6669
specified frame rate. Default -1.
6770
"""
68-
data = bytearray()
69-
data += struct.pack("<i", width)
70-
data += struct.pack("<i", height)
71-
data += struct.pack("<i", quality_level)
72-
data += struct.pack("<f", time_scale)
73-
data += struct.pack("<i", target_frame_rate)
74-
super().queue_message_to_send(data)
71+
msg = OutgoingMessage()
72+
msg.write_int32(width)
73+
msg.write_int32(height)
74+
msg.write_int32(quality_level)
75+
msg.write_float32(time_scale)
76+
msg.write_int32(target_frame_rate)
77+
super().queue_message_to_send(msg)
7578

7679
def set_configuration(self, config: EngineConfig) -> None:
7780
"""
7881
Sets the engine configuration. Takes as input an EngineConfig.
7982
"""
80-
data = bytearray()
81-
data += struct.pack("<iiifi", *config)
82-
super().queue_message_to_send(data)
83+
self.set_configuration_parameters(**config._asdict())
Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
from mlagents_envs.side_channel.side_channel import SideChannel
2-
import struct
1+
from mlagents_envs.side_channel.side_channel import (
2+
SideChannel,
3+
IncomingMessage,
4+
OutgoingMessage,
5+
)
36
import uuid
4-
from typing import Dict, Tuple, Optional, List
7+
from typing import Dict, Optional, List
58

69

710
class FloatPropertiesChannel(SideChannel):
@@ -17,15 +20,14 @@ def __init__(self, channel_id: uuid.UUID = None) -> None:
1720
channel_id = uuid.UUID(("60ccf7d0-4f7e-11ea-b238-784f4387d1f7"))
1821
super().__init__(channel_id)
1922

20-
def on_message_received(self, data: bytes) -> None:
23+
def on_message_received(self, msg: IncomingMessage) -> None:
2124
"""
2225
Is called by the environment to the side channel. Can be called
2326
multiple times per step if multiple messages are meant for that
2427
SideChannel.
25-
Note that Python should never receive an engine configuration from
26-
Unity
2728
"""
28-
k, v = self.deserialize_float_prop(data)
29+
k = msg.read_string()
30+
v = msg.read_float32()
2931
self._float_properties[k] = v
3032

3133
def set_property(self, key: str, value: float) -> None:
@@ -35,7 +37,10 @@ def set_property(self, key: str, value: float) -> None:
3537
:param value: The float value of the property.
3638
"""
3739
self._float_properties[key] = value
38-
super().queue_message_to_send(self.serialize_float_prop(key, value))
40+
msg = OutgoingMessage()
41+
msg.write_string(key)
42+
msg.write_float32(value)
43+
super().queue_message_to_send(msg)
3944

4045
def get_property(self, key: str) -> Optional[float]:
4146
"""
@@ -59,22 +64,3 @@ def get_property_dict_copy(self) -> Dict[str, float]:
5964
:return:
6065
"""
6166
return dict(self._float_properties)
62-
63-
@staticmethod
64-
def serialize_float_prop(key: str, value: float) -> bytearray:
65-
result = bytearray()
66-
encoded_key = key.encode("ascii")
67-
result += struct.pack("<i", len(encoded_key))
68-
result += encoded_key
69-
result += struct.pack("<f", value)
70-
return result
71-
72-
@staticmethod
73-
def deserialize_float_prop(data: bytes) -> Tuple[str, float]:
74-
offset = 0
75-
encoded_key_len = struct.unpack_from("<i", data, offset)[0]
76-
offset = offset + 4
77-
key = data[offset : offset + encoded_key_len].decode("ascii")
78-
offset = offset + encoded_key_len
79-
value = struct.unpack_from("<f", data, offset)[0]
80-
return key, value

ml-agents-envs/mlagents_envs/side_channel/raw_bytes_channel.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
from mlagents_envs.side_channel.side_channel import SideChannel
1+
from mlagents_envs.side_channel.side_channel import (
2+
SideChannel,
3+
IncomingMessage,
4+
OutgoingMessage,
5+
)
26
from typing import List
37
import uuid
48

@@ -13,13 +17,13 @@ def __init__(self, channel_id: uuid.UUID):
1317
self._received_messages: List[bytes] = []
1418
super().__init__(channel_id)
1519

16-
def on_message_received(self, data: bytes) -> None:
20+
def on_message_received(self, msg: IncomingMessage) -> None:
1721
"""
1822
Is called by the environment to the side channel. Can be called
1923
multiple times per step if multiple messages are meant for that
2024
SideChannel.
2125
"""
22-
self._received_messages.append(data)
26+
self._received_messages.append(msg.get_raw_bytes())
2327

2428
def get_and_clear_received_messages(self) -> List[bytes]:
2529
"""
@@ -34,4 +38,6 @@ def send_raw_data(self, data: bytearray) -> None:
3438
Queues a message to be sent by the environment at the next call to
3539
step.
3640
"""
37-
super().queue_message_to_send(data)
41+
msg = OutgoingMessage()
42+
msg.set_raw_bytes(data)
43+
super().queue_message_to_send(msg)

ml-agents-envs/mlagents_envs/side_channel/side_channel.py

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
from abc import ABC, abstractmethod
22
from typing import List
33
import uuid
4+
import struct
5+
6+
import logging
7+
8+
logger = logging.getLogger(__name__)
49

510

611
class SideChannel(ABC):
@@ -16,15 +21,15 @@ def __init__(self, channel_id):
1621
self._channel_id: uuid.UUID = channel_id
1722
self.message_queue: List[bytearray] = []
1823

19-
def queue_message_to_send(self, data: bytearray) -> None:
24+
def queue_message_to_send(self, msg: "OutgoingMessage") -> None:
2025
"""
2126
Queues a message to be sent by the environment at the next call to
2227
step.
2328
"""
24-
self.message_queue.append(data)
29+
self.message_queue.append(msg.buffer)
2530

2631
@abstractmethod
27-
def on_message_received(self, data: bytes) -> None:
32+
def on_message_received(self, msg: "IncomingMessage") -> None:
2833
"""
2934
Is called by the environment to the side channel. Can be called
3035
multiple times per step if multiple messages are meant for that
@@ -39,3 +44,51 @@ def channel_id(self) -> uuid.UUID:
3944
processed in the environment.
4045
"""
4146
return self._channel_id
47+
48+
49+
class OutgoingMessage:
50+
def __init__(self):
51+
self.buffer = bytearray()
52+
53+
def write_int32(self, i: int) -> None:
54+
self.buffer += struct.pack("<i", i)
55+
56+
def write_float32(self, f: float) -> None:
57+
self.buffer += struct.pack("<f", f)
58+
59+
def write_string(self, s: str) -> None:
60+
encoded_key = s.encode("ascii")
61+
self.write_int32(len(encoded_key))
62+
self.buffer += encoded_key
63+
64+
def set_raw_bytes(self, buffer: bytearray) -> None:
65+
if self.buffer:
66+
logger.warning(
67+
"Called set_raw_bytes but the message already has been written to. This will overwrite data."
68+
)
69+
self.buffer = bytearray(buffer)
70+
71+
72+
class IncomingMessage:
73+
def __init__(self, buffer: bytes, offset: int = 0):
74+
self.buffer = buffer
75+
self.offset = offset
76+
77+
def read_int32(self) -> int:
78+
val = struct.unpack_from("<i", self.buffer, self.offset)[0]
79+
self.offset += 4
80+
return val
81+
82+
def read_float32(self) -> float:
83+
val = struct.unpack_from("<f", self.buffer, self.offset)[0]
84+
self.offset += 4
85+
return val
86+
87+
def read_string(self) -> str:
88+
encoded_str_len = self.read_int32()
89+
val = self.buffer[self.offset : self.offset + encoded_str_len].decode("ascii")
90+
self.offset += encoded_str_len
91+
return val
92+
93+
def get_raw_bytes(self) -> bytes:
94+
return bytearray(self.buffer)

ml-agents-envs/mlagents_envs/tests/test_side_channel.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
import struct
21
import uuid
3-
from mlagents_envs.side_channel.side_channel import SideChannel
2+
from mlagents_envs.side_channel.side_channel import (
3+
SideChannel,
4+
IncomingMessage,
5+
OutgoingMessage,
6+
)
47
from mlagents_envs.side_channel.float_properties_channel import FloatPropertiesChannel
58
from mlagents_envs.side_channel.raw_bytes_channel import RawBytesChannel
69
from mlagents_envs.environment import UnityEnvironment
@@ -11,14 +14,14 @@ def __init__(self):
1114
self.list_int = []
1215
super().__init__(uuid.UUID("a85ba5c0-4f87-11ea-a517-784f4387d1f7"))
1316

14-
def on_message_received(self, data):
15-
val = struct.unpack_from("<i", data, 0)[0]
17+
def on_message_received(self, msg: IncomingMessage) -> None:
18+
val = msg.read_int32()
1619
self.list_int += [val]
1720

1821
def send_int(self, value):
19-
data = bytearray()
20-
data += struct.pack("<i", value)
21-
super().queue_message_to_send(data)
22+
msg = OutgoingMessage()
23+
msg.write_int32(value)
24+
super().queue_message_to_send(msg)
2225

2326

2427
def test_int_channel():

0 commit comments

Comments
 (0)