Skip to content

Commit bbc3342

Browse files
KelvinYang0320tsampazk
authored andcommitted
Refactored Deepbots: DeepbotsEnv & Robot Class
1. Inherited from Webots Robot class 2. Refactored SupervisorEnv name to DeepbotsEnv 3. Shortened imports 4. Removed setup folder 5. Renamed lots of class name
1 parent 3ae23e6 commit bbc3342

13 files changed

+107
-97
lines changed

deepbots/robots/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from deepbots.robots.controllers.csv_robot import CSVRobot
2+
from deepbots.robots.controllers.emitter_receiver_robot import EmitterReceiverRobot

deepbots/robots/controllers/robot_emitter_receiver_csv.py renamed to deepbots/robots/controllers/csv_robot.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
from collections.abc import Iterable
22

3-
from deepbots.robots.controllers.robot_emitter_receiver import \
4-
RobotEmitterReceiver
3+
from deepbots.robots.controllers.emitter_receiver_robot import \
4+
EmitterReceiverRobot
55

66

7-
class RobotEmitterReceiverCSV(RobotEmitterReceiver):
7+
class CSVRobot(EmitterReceiverRobot):
88
"""
99
Basic implementation of a robot that can emit and receive messages to/from
1010
the supervisor in string utf-8 form that are Comma Separated Values,
@@ -39,8 +39,8 @@ def initialize_comms(self, emitter_name, receiver_name):
3939
supervisor node
4040
:return: The initialized emitter and receiver references
4141
"""
42-
emitter = self.robot.getDevice(emitter_name)
43-
receiver = self.robot.getDevice(receiver_name)
42+
emitter = self.getDevice(emitter_name)
43+
receiver = self.getDevice(receiver_name)
4444
receiver.enable(self.timestep)
4545
return emitter, receiver
4646

deepbots/robots/controllers/robot_emitter_receiver.py renamed to deepbots/robots/controllers/emitter_receiver_robot.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@
22
from controller import Robot
33

44

5-
class RobotEmitterReceiver:
5+
class EmitterReceiverRobot(Robot):
66
"""
7-
This RobotEmitterReceiver implements only the most basic run method, that
7+
This EmitterReceiverRobot implements only the most basic run method, that
88
steps the robot and calls the handle_emitter, handle_receiver methods that
99
are needed for communication with the supervisor.
1010
1111
This class must be inherited by all robot controllers created by the user
1212
and the handle_emitter, handle_receiver, initialize_comms methods are all
1313
abstract and need to be implemented according to their docstrings. For a
1414
simpler RobotController that implements the methods in a basic form
15-
inherit the RobotEmitterReceiverCSV subclass or other emitter-receiver
15+
inherit the CSVRobot subclass or other emitter-receiver
1616
subclasses.
1717
"""
1818
def __init__(self,
@@ -35,10 +35,10 @@ def __init__(self,
3535
3636
:param timestep: int, positive or None
3737
"""
38-
self.robot = Robot()
38+
super().__init__()
3939

4040
if timestep is None:
41-
self.timestep = int(self.robot.getBasicTimeStep())
41+
self.timestep = int(self.getBasicTimeStep())
4242
else:
4343
self.timestep = timestep
4444

@@ -78,8 +78,8 @@ def initialize_comms(self, emitter_name, receiver_name):
7878
7979
A basic example implementation can be:
8080
81-
emitter = self.robot.getDevice("emitter")
82-
receiver = self.robot.getDevice("receiver")
81+
emitter = self.getDevice("emitter")
82+
receiver = self.getDevice("receiver")
8383
receiver.enable(self.timestep)
8484
return emitter, receiver
8585
@@ -113,6 +113,6 @@ def run(self):
113113
114114
This method should be called by a robot manager to run the robot.
115115
"""
116-
while self.robot.step(self.timestep) != -1:
116+
while self.step(self.timestep) != -1:
117117
self.handle_receiver()
118118
self.handle_emitter()

deepbots/setup/__init__.py

Whitespace-only changes.

deepbots/setup/deepworlds_setup.py

Whitespace-only changes.

deepbots/supervisor/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
from deepbots.supervisor.controllers.robot_supervisor_env import RobotSupervisorEnv
2+
from deepbots.supervisor.controllers.csv_supervisor_env import CSVSupervisorEnv
3+
from deepbots.supervisor.controllers.deepbots_supervisor_env import DeepbotsSupervisorEnv
4+
from deepbots.supervisor.controllers.emitter_receiver_supervisor_env import EmitterReceiverSupervisorEnv
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
from collections.abc import Iterable
2+
3+
from deepbots.supervisor.controllers.emitter_receiver_supervisor_env import EmitterReceiverSupervisorEnv
4+
5+
6+
class CSVSupervisorEnv(EmitterReceiverSupervisorEnv):
7+
"""
8+
This class implements the emitter-receiver scheme using Comma Separated
9+
Values.
10+
"""
11+
def __init__(self,
12+
emitter_name="emitter",
13+
receiver_name="receiver",
14+
timestep=None):
15+
"""
16+
The constructor just passes the arguments provided to the parent
17+
class contructor.
18+
19+
:param emitter_name: The name of the emitter device on the
20+
supervisor node
21+
:param receiver_name: The name of the receiver device on the
22+
supervisor node
23+
:param timestep: The supervisor controller timestep
24+
"""
25+
super(CSVSupervisorEnv, self).__init__(emitter_name, receiver_name,
26+
timestep)
27+
28+
def handle_emitter(self, action):
29+
"""
30+
Implementation of the handle_emitter method expecting an iterable
31+
with Comma Separated Values (CSV).
32+
33+
:param action: Whatever the use-case uses as an action, e.g.
34+
an integer representing discrete actions
35+
:type action: Iterable, for multiple values the CSV format is
36+
required, e.g. [0, 1] for two actions
37+
"""
38+
assert isinstance(action, Iterable), \
39+
"The action object should be Iterable"
40+
41+
message = (",".join(map(str, action))).encode("utf-8")
42+
self.emitter.send(message)
43+
44+
def handle_receiver(self):
45+
"""
46+
Implementation of the handle_receiver method expecting an iterable
47+
with Comma Separated Values (CSV).
48+
49+
:return: Returns the message received from the robot, returns None
50+
if no message is received
51+
:rtype: List of string values
52+
"""
53+
if self.receiver.getQueueLength() > 0:
54+
try:
55+
string_message = self.receiver.getString()
56+
except AttributeError:
57+
string_message = self.receiver.getData().decode("utf-8")
58+
self.receiver.nextPacket()
59+
return string_message.split(",")
60+
else:
61+
return None

deepbots/supervisor/controllers/supervisor_env.py renamed to deepbots/supervisor/controllers/deepbots_supervisor_env.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from controller import Supervisor
33

44

5-
class SupervisorEnv(Supervisor, gym.Env):
5+
class DeepbotsSupervisorEnv(Supervisor, gym.Env):
66
"""
77
This class is the highest class in deepbots class hierarchy, inheriting
88
both the Webots Supervisor controller and the basic gym.Env.
@@ -18,7 +18,7 @@ class SupervisorEnv(Supervisor, gym.Env):
1818
compatible with reinforcement learning agents that work with
1919
the gym interface. Moreover, a problem-agnostic reset method is
2020
provided. Please use any of the children supervisor classes to be
21-
inherited by your own class, such as the RobotSupervisor class.
21+
inherited by your own class, such as the RobotSupervisorEnv class.
2222
Nevertheless, advanced users can inherit this class to create
2323
their own supervisor classes if they wish.
2424
"""

deepbots/supervisor/controllers/supervisor_emitter_receiver.py renamed to deepbots/supervisor/controllers/emitter_receiver_supervisor_env.py

Lines changed: 3 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
from collections.abc import Iterable
21
from warnings import warn, simplefilter
32

4-
from deepbots.supervisor.controllers.supervisor_env import SupervisorEnv
3+
from deepbots.supervisor.controllers.deepbots_supervisor_env import DeepbotsSupervisorEnv
54
from controller import Supervisor
65

76

8-
class SupervisorEmitterReceiver(SupervisorEnv):
7+
class EmitterReceiverSupervisorEnv(DeepbotsSupervisorEnv):
98
"""
109
This is the base class for the emitter - receiver scheme.
1110
@@ -26,7 +25,7 @@ def __init__(self,
2625
supervisor node
2726
:param timestep: The supervisor controller timestep
2827
"""
29-
super(SupervisorEmitterReceiver, self).__init__()
28+
super(EmitterReceiverSupervisorEnv, self).__init__()
3029

3130
if timestep is None:
3231
self.timestep = int(self.getBasicTimeStep())
@@ -116,61 +115,3 @@ def timestep(self, value):
116115
:param value: The new controller timestep in milliseconds
117116
"""
118117
self._timestep = int(value)
119-
120-
121-
class SupervisorCSV(SupervisorEmitterReceiver):
122-
"""
123-
This class implements the emitter-receiver scheme using Comma Separated
124-
Values.
125-
"""
126-
def __init__(self,
127-
emitter_name="emitter",
128-
receiver_name="receiver",
129-
timestep=None):
130-
"""
131-
The constructor just passes the arguments provided to the parent
132-
class contructor.
133-
134-
:param emitter_name: The name of the emitter device on the
135-
supervisor node
136-
:param receiver_name: The name of the receiver device on the
137-
supervisor node
138-
:param timestep: The supervisor controller timestep
139-
"""
140-
super(SupervisorCSV, self).__init__(emitter_name, receiver_name,
141-
timestep)
142-
143-
def handle_emitter(self, action):
144-
"""
145-
Implementation of the handle_emitter method expecting an iterable
146-
with Comma Separated Values (CSV).
147-
148-
:param action: Whatever the use-case uses as an action, e.g.
149-
an integer representing discrete actions
150-
:type action: Iterable, for multiple values the CSV format is
151-
required, e.g. [0, 1] for two actions
152-
"""
153-
assert isinstance(action, Iterable), \
154-
"The action object should be Iterable"
155-
156-
message = (",".join(map(str, action))).encode("utf-8")
157-
self.emitter.send(message)
158-
159-
def handle_receiver(self):
160-
"""
161-
Implementation of the handle_receiver method expecting an iterable
162-
with Comma Separated Values (CSV).
163-
164-
:return: Returns the message received from the robot, returns None
165-
if no message is received
166-
:rtype: List of string values
167-
"""
168-
if self.receiver.getQueueLength() > 0:
169-
try:
170-
string_message = self.receiver.getString()
171-
except AttributeError:
172-
string_message = self.receiver.getData().decode("utf-8")
173-
self.receiver.nextPacket()
174-
return string_message.split(",")
175-
else:
176-
return None

deepbots/supervisor/controllers/robot_supervisor.py renamed to deepbots/supervisor/controllers/robot_supervisor_env.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
from warnings import warn, simplefilter
2-
from deepbots.supervisor.controllers.supervisor_env import SupervisorEnv
2+
from deepbots.supervisor.controllers.deepbots_supervisor_env import DeepbotsSupervisorEnv
33
from controller import Supervisor
44

55

6-
class RobotSupervisor(SupervisorEnv):
6+
class RobotSupervisorEnv(DeepbotsSupervisorEnv):
77
"""
8-
The RobotSupervisor class implements both a robot controller and a
8+
The RobotSupervisorEnv class implements both a robot controller and a
99
supervisor RL environment, referred to as Robot-Supervisor scheme.
1010
1111
This class can be used when there is no need to separate the Robot
@@ -18,17 +18,17 @@ class RobotSupervisor(SupervisorEnv):
1818
1919
The user needs to implement the regular methods for the environment,
2020
reward(), get_observations(), get_default_observation, etc., from
21-
SupervisorEnv according to their use-case in addition to the method
21+
DeepbotsSupervisorEnv according to their use-case in addition to the method
2222
apply_action() introduced here.
2323
2424
apply_action():
25-
(similar to use_message_data() of RobotEmitterReceiverCSV)
25+
(similar to use_message_data() of CSVRobot)
2626
This method takes an action argument and translates it to a robot
2727
action, e.g. motor speeds.
2828
Note that apply_action() is called during step().
2929
"""
3030
def __init__(self, timestep=None):
31-
super(RobotSupervisor, self).__init__()
31+
super(RobotSupervisorEnv, self).__init__()
3232

3333
if timestep is None:
3434
self.timestep = int(self.getBasicTimeStep())
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from deepbots.supervisor.wrappers.keyboard_printer import KeyboardPrinter
2+
from deepbots.supervisor.wrappers.tensorboard_wrapper import TensorboardLogger

deepbots/supervisor/wrappers/keyboard_printer.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
from controller import Keyboard
22

3-
from deepbots.supervisor.controllers.supervisor_env import SupervisorEnv
3+
from deepbots.supervisor.controllers.deepbots_supervisor_env import DeepbotsSupervisorEnv
44

55

6-
class KeyboardPrinter(SupervisorEnv):
6+
class KeyboardPrinter(DeepbotsSupervisorEnv):
77
def __init__(self, controller):
88
self.controller = controller
99
self.keyboard = Keyboard()
1010
self.keyboard.enable(self.controller.timestep)
1111

1212
def step(self, action):
13-
observation, reward, isDone, info = self.controller.step(action)
13+
observation, reward, is_done, info = self.controller.step(action)
1414
key = self.keyboard.getKey()
1515
# DEBUG CONTROLS
1616
if key == Keyboard.CONTROL + ord("A"):
@@ -23,13 +23,13 @@ def step(self, action):
2323
print()
2424
print("Observations: ", self.controller.observation)
2525

26-
return observation, reward, isDone, info
26+
return observation, reward, is_done, info
2727

2828
def is_done(self):
29-
isDone = self.controller.is_done()
30-
if isDone:
29+
is_done = self.controller.is_done()
30+
if is_done:
3131
print("Done")
32-
return isDone
32+
return is_done
3333

3434
def get_observations(self):
3535
return self.controller.get_observations()

deepbots/supervisor/wrappers/tensorboard_wrapper.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import numpy as np
22
from tensorboardX import SummaryWriter
33

4-
from deepbots.supervisor.controllers.supervisor_env import SupervisorEnv
4+
from deepbots.supervisor.controllers.deepbots_supervisor_env import DeepbotsSupervisorEnv
55

66

7-
class TensorboardLogger(SupervisorEnv):
7+
class TensorboardLogger(DeepbotsSupervisorEnv):
88
def __init__(self,
99
controller,
1010
log_dir="logs/results",
@@ -29,7 +29,7 @@ def __init__(self,
2929
self.file_writer = SummaryWriter(log_dir, flush_secs=30)
3030

3131
def step(self, action):
32-
observation, reward, isDone, info = self.controller.step(action)
32+
observation, reward, is_done, info = self.controller.step(action)
3333

3434
if (self.v_action > 1):
3535
self.file_writer.add_histogram(
@@ -47,7 +47,7 @@ def step(self, action):
4747
self.file_writer.add_scalar("Rewards/Per Global Step", reward,
4848
self.step_global)
4949

50-
if (isDone):
50+
if (is_done):
5151
self.file_writer.add_scalar(
5252
"Is Done/Per Reset step",
5353
self.step_cntr,
@@ -60,13 +60,13 @@ def step(self, action):
6060
self.step_cntr += 1
6161
self.step_global += 1
6262

63-
return observation, reward, isDone, info
63+
return observation, reward, is_done, info
6464

6565
def is_done(self):
66-
isDone = self.controller.is_done()
66+
is_done = self.controller.is_done()
6767

6868
self.file_writer.flush()
69-
return isDone
69+
return is_done
7070

7171
def get_observations(self):
7272
obs = self.controller.get_observations()

0 commit comments

Comments
 (0)