-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgazebo_env.py
153 lines (124 loc) · 5.45 KB
/
gazebo_env.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
import gym
import rospy
#import roslaunch
import sys
import os
import signal
import subprocess
import time
from std_srvs.srv import Empty
import random
from rosgraph_msgs.msg import Clock
import time
class GazeboEnv(gym.Env):
"""Superclass for all Gazebo environments.
"""
metadata = {'render.modes': ['human']}
def __init__(self, launchfile):
# self.last_clock_msg = Clock()
random_number = random.randint(10000, 15000)
self.port = "11311"#str(random_number) #os.environ["ROS_PORT_SIM"]
self.port_gazebo = "11345"#str(random_number+1) #os.environ["ROS_PORT_SIM"]
# self.port = str(random_number) #os.environ["ROS_PORT_SIM"]
# self.port_gazebo = str(random_number+1) #os.environ["ROS_PORT_SIM"]
os.environ["ROS_MASTER_URI"] = "http://localhost:"+self.port
os.environ["GAZEBO_MASTER_URI"] = "http://localhost:"+self.port_gazebo
#
# self.ros_master_uri = os.environ["ROS_MASTER_URI"];
print("ROS_MASTER_URI=http://localhost:"+self.port + "\n")
print("GAZEBO_MASTER_URI=http://localhost:"+self.port_gazebo + "\n")
# self.port = os.environ.get("ROS_PORT_SIM", "11311")
ros_path = os.path.dirname(subprocess.check_output(["which", "roscore"]))
# NOTE: It doesn't make sense to launch a roscore because it will be done when spawing Gazebo, which also need
# to be the first node in order to initialize the clock.
# # start roscore with same python version as current script
# self._roscore = subprocess.Popen([sys.executable, os.path.join(ros_path, b"roscore"), "-p", self.port])
# time.sleep(1)
# print ("Roscore launched!")
if launchfile.startswith("/"):
fullpath = launchfile
else:
fullpath = os.path.join(os.path.dirname(__file__), "launch", launchfile)
if not os.path.exists(fullpath):
raise IOError("File "+fullpath+" does not exist")
# self._roslaunch = subprocess.Popen([sys.executable, os.path.join(ros_path, b"roslaunch"), "-p", self.port, fullpath])
print ("Gazebo launched!")
# time.sleep(10)
self.gzclient_pid = 0
# Launch the simulation with the given launchfile name
rospy.init_node('gym', anonymous=True)
################################################################################################################
# r = rospy.Rate(1)
# self.clock_sub = rospy.Subscriber('/clock', Clock, self.callback, queue_size=1000000)
# while not rospy.is_shutdown():
# print("initialization: ", rospy.rostime.is_rostime_initialized())
# print("Wallclock: ", rospy.rostime.is_wallclock())
# print("Time: ", time.time())
# print("Rospyclock: ", rospy.rostime.get_rostime().secs)
# # print("/clock: ", str(self.last_clock_msg))
# last_ros_time_ = self.last_clock_msg
# print("Clock:", last_ros_time_)
# # print("Waiting for synch with ROS clock")
# # if wallclock == False:
# # break
# r.sleep()
################################################################################################################
# def callback(self, message):
# """
# Callback method for the subscriber of the clock topic
# :param message:
# :return:
# """
# # self.last_clock_msg = int(str(message.clock.secs) + str(message.clock.nsecs)) / 1e6
# # print("Message", message)
# self.last_clock_msg = message
# # print("Message", message)
def step(self, action):
# Implement this method in every subclass
# Perform a step in gazebo. E.g. move the robot
raise NotImplementedError
def reset(self):
# Implemented in subclass
raise NotImplementedError
def _render(self, mode="human", close=False):
if close:
tmp = os.popen("ps -Af").read()
proccount = tmp.count('gzclient')
if proccount > 0:
if self.gzclient_pid != 0:
os.kill(self.gzclient_pid, signal.SIGTERM)
os.wait()
return
tmp = os.popen("ps -Af").read()
proccount = tmp.count('gzclient')
if proccount < 1:
subprocess.Popen("gzclient")
self.gzclient_pid = int(subprocess.check_output(["pidof","-s","gzclient"]))
else:
self.gzclient_pid = 0
def _close(self):
# Kill gzclient, gzserver and roscore
tmp = os.popen("ps -Af").read()
gzclient_count = tmp.count('gzclient')
gzserver_count = tmp.count('gzserver')
roscore_count = tmp.count('roscore')
rosmaster_count = tmp.count('rosmaster')
if gzclient_count > 0:
os.system("killall -9 gzclient")
if gzserver_count > 0:
os.system("killall -9 gzserver")
if rosmaster_count > 0:
os.system("killall -9 rosmaster")
if roscore_count > 0:
os.system("killall -9 roscore")
if (gzclient_count or gzserver_count or roscore_count or rosmaster_count >0):
os.wait()
def _configure(self):
# TODO
# From OpenAI API: Provides runtime configuration to the enviroment
# Maybe set the Real Time Factor?
pass
def _seed(self):
# TODO
# From OpenAI API: Sets the seed for this env's random number generator(s)
pass