Updates to comply with C++/C#
This commit is contained in:
parent
fe09a5695d
commit
e53a01bb50
@ -11,15 +11,16 @@ from Things.TouchSensor import TouchSensor
|
|||||||
# Create a local participant for handling communcation
|
# Create a local participant for handling communcation
|
||||||
# using default settings (UDP communciation over port 7681)
|
# using default settings (UDP communciation over port 7681)
|
||||||
participant = ParticipantUDP(port=7681, local_port=7682, ip_address="127.0.0.1")
|
participant = ParticipantUDP(port=7681, local_port=7682, ip_address="127.0.0.1")
|
||||||
|
|
||||||
# The robot's propulsion is a differential drive
|
# The robot's propulsion is a differential drive
|
||||||
bb2b = DifferentialDrive(participant)
|
bb2b = DifferentialDrive(participant)
|
||||||
bb2b.name = "BB2B"
|
bb2b.name = "BB2B"
|
||||||
bb2b.SetDriveDimensions(0.064, 0.128)
|
bb2b.SetDriveDimensions(0.064, 0.128)
|
||||||
bb2b.SetOrientation(SwingTwist.Degrees(40, 0, 0))
|
bb2b.SetOrientation(SwingTwist.Degrees(40, 0, 0))
|
||||||
bb2b.SetPosition(Spherical(0.15, Direction.up))
|
# bb2b.SetPosition(Spherical(0.15, Direction.up))
|
||||||
|
|
||||||
model = Thing(parent=bb2b)
|
model = Thing(parent=bb2b)
|
||||||
model.model_url = "https://passer.life/extras/Roller1anim1.png"
|
model.model_url = "https://passer.life/extras/Roller2anim1.png"
|
||||||
model.SetOrientation(SwingTwist.Degrees(90, 0, 0))
|
model.SetOrientation(SwingTwist.Degrees(90, 0, 0))
|
||||||
|
|
||||||
# It has a touch sensor at the front left of the roboid
|
# It has a touch sensor at the front left of the roboid
|
||||||
@ -49,4 +50,4 @@ while True:
|
|||||||
# Update the roboid state
|
# Update the roboid state
|
||||||
participant.Update()
|
participant.Update()
|
||||||
# and sleep for 100ms
|
# and sleep for 100ms
|
||||||
time.sleep(0.1)
|
time.sleep(1)
|
||||||
|
@ -9,6 +9,7 @@ class BinaryMsg():
|
|||||||
self.thing_id = data[2]
|
self.thing_id = data[2]
|
||||||
self.data = data[3:]
|
self.data = data[3:]
|
||||||
else:
|
else:
|
||||||
|
self.network_id = data
|
||||||
self.thing_id = thing.id
|
self.thing_id = thing.id
|
||||||
self.thing = thing
|
self.thing = thing
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ class ModelUrlMsg(IMessage):
|
|||||||
self.url = data[ModelUrlMsg.length:].decode("utf-8")
|
self.url = data[ModelUrlMsg.length:].decode("utf-8")
|
||||||
else:
|
else:
|
||||||
if thing is not None:
|
if thing is not None:
|
||||||
|
self.network_id = data
|
||||||
self.thing_id = thing.id
|
self.thing_id = thing.id
|
||||||
self.url = thing.model_url
|
self.url = thing.model_url
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ class NameMsg(IMessage):
|
|||||||
self.name = data[NameMsg.length:].decode("utf-8")
|
self.name = data[NameMsg.length:].decode("utf-8")
|
||||||
else:
|
else:
|
||||||
if thing is not None:
|
if thing is not None:
|
||||||
|
self.network_id = data
|
||||||
self.thing_id = thing.id
|
self.thing_id = thing.id
|
||||||
self.name = thing.name
|
self.name = thing.name
|
||||||
|
|
||||||
|
@ -7,10 +7,13 @@ class NetworkIdMsg(IMessage):
|
|||||||
id = 0xA1
|
id = 0xA1
|
||||||
length = 2
|
length = 2
|
||||||
|
|
||||||
|
|
||||||
## Create a network id message
|
## Create a network id message
|
||||||
def __init__(self, data = None):
|
def __init__(self, arg1 = None):
|
||||||
pass
|
if isinstance(arg1, bytes):
|
||||||
|
buffer = arg1
|
||||||
|
self.network_id = buffer[1]
|
||||||
|
else:
|
||||||
|
self.network_id = arg1
|
||||||
|
|
||||||
## Serialize the message into the given buffer
|
## Serialize the message into the given buffer
|
||||||
#
|
#
|
||||||
@ -20,7 +23,7 @@ class NetworkIdMsg(IMessage):
|
|||||||
buffer: bytearray = buffer_ref[0]
|
buffer: bytearray = buffer_ref[0]
|
||||||
buffer[0:NetworkIdMsg.length] = [
|
buffer[0:NetworkIdMsg.length] = [
|
||||||
NetworkIdMsg.id,
|
NetworkIdMsg.id,
|
||||||
0
|
self.network_id
|
||||||
]
|
]
|
||||||
return NetworkIdMsg.length
|
return NetworkIdMsg.length
|
||||||
|
|
||||||
|
@ -24,6 +24,8 @@ class ParticipantMsg(IMessage):
|
|||||||
if buffer_ref is None:
|
if buffer_ref is None:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
print(f'Send ParticipantMsg [0]')
|
||||||
|
|
||||||
buffer: bytearray = buffer_ref[0]
|
buffer: bytearray = buffer_ref[0]
|
||||||
buffer[0:ParticipantMsg.length] = [
|
buffer[0:ParticipantMsg.length] = [
|
||||||
ParticipantMsg.id,
|
ParticipantMsg.id,
|
||||||
|
@ -10,8 +10,15 @@ class PoseMsg():
|
|||||||
LinearVelocity = 0x04
|
LinearVelocity = 0x04
|
||||||
AngularVelocity = 0x08
|
AngularVelocity = 0x08
|
||||||
|
|
||||||
def __init__(self, thing, force: bool = False):
|
def __init__(self, arg1, thing, force: bool = False):
|
||||||
|
if isinstance(arg1, bytes):
|
||||||
|
self.thing_id = arg1[2]
|
||||||
|
self.data = arg1[3:]
|
||||||
|
else:
|
||||||
|
self.network_id = arg1
|
||||||
self.thing = thing
|
self.thing = thing
|
||||||
|
self.network_id = 0
|
||||||
|
|
||||||
self.pose_type = 0
|
self.pose_type = 0
|
||||||
if thing.position_updated or force:
|
if thing.position_updated or force:
|
||||||
self.pose_type |= PoseMsg.Position
|
self.pose_type |= PoseMsg.Position
|
||||||
@ -30,10 +37,12 @@ class PoseMsg():
|
|||||||
if self.thing is None or self.pose_type == 0:
|
if self.thing is None or self.pose_type == 0:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
print(f'Send PoseMsg [{self.network_id}/{self.thing.id}] {self.pose_type}')
|
||||||
|
|
||||||
buffer: bytearray = buffer_ref[0]
|
buffer: bytearray = buffer_ref[0]
|
||||||
buffer[0:PoseMsg.length] = [
|
buffer[0:PoseMsg.length] = [
|
||||||
PoseMsg.id,
|
PoseMsg.id,
|
||||||
0, # network_id,
|
self.network_id,
|
||||||
self.thing.id,
|
self.thing.id,
|
||||||
self.pose_type
|
self.pose_type
|
||||||
]
|
]
|
||||||
|
@ -8,13 +8,16 @@ class ThingMsg(IMessage):
|
|||||||
thing_type = None
|
thing_type = None
|
||||||
parent_id = None
|
parent_id = None
|
||||||
|
|
||||||
def __init__(self, data, thing=None):
|
def __init__(self, arg1, thing=None):
|
||||||
if isinstance(data, bytes):
|
if isinstance(arg1, bytes):
|
||||||
self.thing_id = data[2]
|
buffer = arg1
|
||||||
self.thing_type = data[3]
|
self.network_id = buffer[1]
|
||||||
self.parent_id = data[4]
|
self.thing_id = buffer[2]
|
||||||
|
self.thing_type = buffer[3]
|
||||||
|
self.parent_id = buffer[4]
|
||||||
else:
|
else:
|
||||||
if thing is not None:
|
if thing is not None:
|
||||||
|
self.network_id = arg1
|
||||||
self.thing_id = thing.id
|
self.thing_id = thing.id
|
||||||
self.thing_type = thing.type
|
self.thing_type = thing.type
|
||||||
if thing.parent is not None:
|
if thing.parent is not None:
|
||||||
@ -26,10 +29,12 @@ class ThingMsg(IMessage):
|
|||||||
if self.thing_id is None:
|
if self.thing_id is None:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
print(f'Send ThingMsg [{self.network_id}/{self.thing_id}] {self.thing_type} {self.parent_id}')
|
||||||
|
|
||||||
buffer: bytearray = buffer_ref[0]
|
buffer: bytearray = buffer_ref[0]
|
||||||
buffer[0:ThingMsg.length] = [
|
buffer[0:ThingMsg.length] = [
|
||||||
ThingMsg.id,
|
ThingMsg.id,
|
||||||
0, # network_id,
|
self.network_id,
|
||||||
self.thing_id,
|
self.thing_id,
|
||||||
self.thing_type,
|
self.thing_type,
|
||||||
self.parent_id
|
self.parent_id
|
||||||
|
@ -15,6 +15,9 @@ class Participant:
|
|||||||
## The port number for UDP communication with the participant. This is 0 for isolated participants.
|
## The port number for UDP communication with the participant. This is 0 for isolated participants.
|
||||||
self.port = port
|
self.port = port
|
||||||
|
|
||||||
|
## The network ID of the participant
|
||||||
|
self.network_id =0
|
||||||
|
|
||||||
## The things managed by this participant
|
## The things managed by this participant
|
||||||
self.things = set()
|
self.things = set()
|
||||||
|
|
||||||
|
@ -42,19 +42,19 @@ class ParticipantUDP(Participant):
|
|||||||
|
|
||||||
## True if the participant is running isolated.
|
## True if the participant is running isolated.
|
||||||
# Isolated participants do not communicate with other participants
|
# Isolated participants do not communicate with other participants
|
||||||
self.isolated = True
|
self.is_isolated = True
|
||||||
|
self.remote_site = None
|
||||||
|
|
||||||
## The other participants communicating with this participant
|
## The other participants communicating with this participant
|
||||||
self.others = []
|
self.others = []
|
||||||
|
|
||||||
if self.port != 0:
|
if self.port != 0:
|
||||||
self.isolated = False
|
self.is_isolated = False
|
||||||
if ip_address is not None:
|
if ip_address is not None:
|
||||||
self.others.append(Participant(ip_address, port))
|
self.remote_site = Participant(ip_address, port)
|
||||||
|
self.others.append(self.remote_site)
|
||||||
|
|
||||||
self.buffer = bytearray(256)
|
self.buffer = bytearray(256)
|
||||||
# self.thing_msg_processors = {}
|
|
||||||
# self.new_thing_handlers = []
|
|
||||||
self.publishInterval = 3000 # 3 seconds
|
self.publishInterval = 3000 # 3 seconds
|
||||||
|
|
||||||
self.udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
self.udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||||
@ -92,33 +92,55 @@ class ParticipantUDP(Participant):
|
|||||||
if currentTimeMs is None:
|
if currentTimeMs is None:
|
||||||
currentTimeMs = time.time() * 1000
|
currentTimeMs = time.time() * 1000
|
||||||
|
|
||||||
if self.isolated == False:
|
if self.is_isolated == False:
|
||||||
if self.publishInterval > 0 and currentTimeMs > self.nextPublishMe:
|
if self.publishInterval > 0 and currentTimeMs > self.nextPublishMe:
|
||||||
msg = ParticipantMsg()
|
msg = ParticipantMsg(self.network_id)
|
||||||
if self.others.count == 0:
|
if self.remote_site == None:
|
||||||
self.Publish(msg)
|
self.Publish(msg)
|
||||||
else:
|
else:
|
||||||
for other_participant in self.others:
|
self.Send(self.remote_site, msg)
|
||||||
self.Send(other_participant, msg)
|
|
||||||
|
|
||||||
print(f'Publish ParticipantMsg')
|
|
||||||
self.nextPublishMe = currentTimeMs + self.publishInterval
|
self.nextPublishMe = currentTimeMs + self.publishInterval
|
||||||
|
|
||||||
for thing in self.things:
|
self.UpdateMyThings(currentTimeMs)
|
||||||
thing.Update(currentTimeMs)
|
# for thing in self.things:
|
||||||
|
# thing.Update(currentTimeMs)
|
||||||
|
|
||||||
super().Update(currentTimeMs)
|
# super().Update(currentTimeMs)
|
||||||
|
|
||||||
|
def UpdateMyThings(self, currentTimeMs):
|
||||||
|
for thing in self.things:
|
||||||
|
if thing is None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# if thing.hierarchyChanged and not (self.isIsolated or self.network_id == ):
|
||||||
|
# thingMsg = ThingMsg(self.network_id, thing)
|
||||||
|
# self.Send(self.remote_site, thingMsg)
|
||||||
|
|
||||||
|
thing.Update(currentTimeMs, False)
|
||||||
|
if not(self.is_isolated or self.network_id == 0):
|
||||||
|
# if thing.terminate:
|
||||||
|
# destroyMsg = DestroyMsg(self.network_id, thing)
|
||||||
|
# self.Send(self.remote_site, destroyMsg)
|
||||||
|
# else:
|
||||||
|
# Send to remote site
|
||||||
|
poseMsg = PoseMsg(thing.owner.network_id, thing)
|
||||||
|
self.Send(self.remote_site, poseMsg)
|
||||||
|
binaryMsg = BinaryMsg(thing.owner.network_id, thing)
|
||||||
|
self.Send(self.remote_site, binaryMsg)
|
||||||
|
# if thing.terminate:
|
||||||
|
# self.Remove(thing)
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Send
|
#region Send
|
||||||
|
|
||||||
def SendThingInfo(self, owner, thing, recursively: bool = False):
|
def SendThingInfo(self, owner, thing, recursively: bool = False):
|
||||||
self.Send(owner, ThingMsg(thing))
|
self.Send(owner, ThingMsg(self.network_id, thing))
|
||||||
self.Send(owner, NameMsg(thing))
|
self.Send(owner, NameMsg(self.network_id, thing))
|
||||||
self.Send(owner, ModelUrlMsg(thing))
|
self.Send(owner, ModelUrlMsg(self.network_id, thing))
|
||||||
self.Send(owner, PoseMsg(thing, True))
|
#self.Send(owner, PoseMsg(self.network_id, thing, True))
|
||||||
self.Send(owner, BinaryMsg(thing))
|
self.Send(owner, BinaryMsg(self.network_id, thing))
|
||||||
|
|
||||||
if recursively:
|
if recursively:
|
||||||
for child in thing.children:
|
for child in thing.children:
|
||||||
@ -130,7 +152,7 @@ class ParticipantUDP(Participant):
|
|||||||
if buffer_size <= 0:
|
if buffer_size <= 0:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
print(f'{self.name} send {self.buffer[0]} to {owner.ip_address} {owner.port}')
|
# print(f'{self.name} send {self.buffer[0]} to {owner.ip_address} {owner.port}')
|
||||||
self.udp_socket.sendto(self.buffer[:buffer_size], (owner.ip_address, owner.port))
|
self.udp_socket.sendto(self.buffer[:buffer_size], (owner.ip_address, owner.port))
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@ -149,6 +171,7 @@ class ParticipantUDP(Participant):
|
|||||||
|
|
||||||
def Receiver(self):
|
def Receiver(self):
|
||||||
while True:
|
while True:
|
||||||
|
try:
|
||||||
data, addr = self.udp_socket.recvfrom(1024)
|
data, addr = self.udp_socket.recvfrom(1024)
|
||||||
remote_ip_address = addr[0]
|
remote_ip_address = addr[0]
|
||||||
remote_port = addr[1]
|
remote_port = addr[1]
|
||||||
@ -158,6 +181,9 @@ class ParticipantUDP(Participant):
|
|||||||
# print(f'new participant')
|
# print(f'new participant')
|
||||||
remote_participant = self.AddParticipant(remote_ip_address, remote_port)
|
remote_participant = self.AddParticipant(remote_ip_address, remote_port)
|
||||||
self.ReceiveData(data, remote_participant)
|
self.ReceiveData(data, remote_participant)
|
||||||
|
except ConnectionError:
|
||||||
|
self.network_id = 0
|
||||||
|
pass
|
||||||
|
|
||||||
def ReceiveData(self, data, sender):
|
def ReceiveData(self, data, sender):
|
||||||
msgId = data[0]
|
msgId = data[0]
|
||||||
@ -166,7 +192,7 @@ class ParticipantUDP(Participant):
|
|||||||
case ParticipantMsg.id:
|
case ParticipantMsg.id:
|
||||||
self.ProcessParticipantMsg(sender, ParticipantMsg(data))
|
self.ProcessParticipantMsg(sender, ParticipantMsg(data))
|
||||||
case NetworkIdMsg.id:
|
case NetworkIdMsg.id:
|
||||||
self.ProcessNetworkIdMsg(sender, NetworkIdMsg(data))
|
self.ProcessSiteIdMsg(sender, NetworkIdMsg(data))
|
||||||
# case InvestigateMsg.id:
|
# case InvestigateMsg.id:
|
||||||
# self.ProcessInvestigateMsg(InvestigateMsg(data))
|
# self.ProcessInvestigateMsg(InvestigateMsg(data))
|
||||||
case ThingMsg.id:
|
case ThingMsg.id:
|
||||||
@ -181,11 +207,12 @@ class ParticipantUDP(Participant):
|
|||||||
def ProcessParticipantMsg(self, sender, msg: ParticipantMsg):
|
def ProcessParticipantMsg(self, sender, msg: ParticipantMsg):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def ProcessNetworkIdMsg(self, sender, msg: NetworkIdMsg):
|
def ProcessSiteIdMsg(self, sender, msg: NetworkIdMsg):
|
||||||
print(f'{self.name} receive network id')
|
print(f'{self.name} Process SiteMsg {self.network_id} -> {msg.network_id}')
|
||||||
print(f'sending all things {len(self.things)}')
|
if self.network_id != msg.network_id:
|
||||||
|
self.network_id = msg.network_id
|
||||||
for thing in self.things:
|
for thing in self.things:
|
||||||
if thing.parent is None:
|
#if thing.parent is None:
|
||||||
self.SendThingInfo(sender, thing, recursively=True)
|
self.SendThingInfo(sender, thing, recursively=True)
|
||||||
|
|
||||||
def ProcessInvestigateMsg(self, data: bytearray):
|
def ProcessInvestigateMsg(self, data: bytearray):
|
||||||
|
9
Thing.py
9
Thing.py
@ -100,10 +100,11 @@ class Thing:
|
|||||||
self.angular_velocity = angular_velocity
|
self.angular_velocity = angular_velocity
|
||||||
self.angular_velocity_updated = True
|
self.angular_velocity_updated = True
|
||||||
|
|
||||||
def Update(self, currentTime):
|
def Update(self, currentTime, recurse = False):
|
||||||
pose_msg = PoseMsg(self)
|
# pose_msg = PoseMsg(self.owner.network_id, self)
|
||||||
for other in self.owner.others:
|
# for other in self.owner.others:
|
||||||
self.owner.Send(other, pose_msg)
|
# self.owner.Send(other, pose_msg)
|
||||||
|
pass
|
||||||
|
|
||||||
def SetParent(self, parent):
|
def SetParent(self, parent):
|
||||||
if parent is None:
|
if parent is None:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user