Skip to content

Commit ad0ebb6

Browse files
committed
add autonomous state display
1 parent d336620 commit ad0ebb6

File tree

13 files changed

+351
-58
lines changed

13 files changed

+351
-58
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?xml version="1.0"?>
2+
<launch>
3+
<arg name="serial_port" default="/dev/ttyS0" />
4+
<node pkg="autonomous_state_display" exec="autonomous_state_display" output="screen">
5+
<param name="serial_port" value="$(var serial_port)" />
6+
</node>
7+
</launch>
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?xml version="1.0"?>
2+
<package format="2">
3+
<name>autonomous_state_display</name>
4+
<version>0.1.0</version>
5+
<description>The autonomous state display package</description>
6+
7+
<maintainer email="makoto.yabuta@tier4.jp">yabuta</maintainer>
8+
9+
<license>Apache License 2.0</license>
10+
<exec_depend>ament_index_python</exec_depend>
11+
<exec_depend>signage_version</exec_depend>
12+
13+
<depend>autoware_auto_system_msgs</depend>
14+
<depend>diagnostic_updater</depend>
15+
<depend>python-pulsectl-pip</depend>
16+
<depend>rclpy</depend>
17+
<depend>std_srvs</depend>
18+
<depend>tier4_api_msgs</depend>
19+
<depend>tier4_debug_msgs</depend>
20+
<depend>tier4_external_api_msgs</depend>
21+
<depend>tier4_hmi_msgs</depend>
22+
23+
<export>
24+
<build_type>ament_python</build_type>
25+
</export>
26+
</package>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[develop]
2+
script_dir=$base/lib/autonomous_state_display
3+
[install]
4+
install_scripts=$base/lib/autonomous_state_display
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#!/usr/bin/env python3
2+
3+
import os
4+
5+
from setuptools import setup
6+
7+
8+
def package_files(directory):
9+
paths = []
10+
for (path, directories, filenames) in os.walk(directory):
11+
for filename in filenames:
12+
paths.append(os.path.join(path, filename))
13+
return paths
14+
15+
16+
package_name = "autonomous_state_display"
17+
setup(
18+
name=package_name,
19+
version="0.1.0",
20+
package_dir={"": "src"},
21+
packages=[package_name],
22+
data_files=[
23+
("share/" + package_name, ["package.xml"]),
24+
("share/" + package_name + "/launch", ["launch/autonomous_state_display.launch.xml"]),
25+
],
26+
install_requires=["setuptools"],
27+
zip_safe=True,
28+
author="Makoto Yabuta",
29+
maintainer="Makoto Yabuta",
30+
maintainer_email="makoto.yabuta@tier4.jp",
31+
keywords=["ROS"],
32+
classifiers=[
33+
"Intended Audience :: Developers",
34+
"License :: OSI Approved :: Apache Software License",
35+
"Programming Language :: Python",
36+
"Topic :: Software Development",
37+
],
38+
description=("autonomous_state_display provides a GUI to display autonomous state."),
39+
license="TODO",
40+
entry_points={
41+
"console_scripts": [
42+
"autonomous_state_display = autonomous_state_display.autonomous_state_display:main",
43+
]
44+
},
45+
)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# This Python file uses the following encoding: utf-8
2+
3+
# if__name__ == "__main__":
4+
# pass
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# This Python file uses the following encoding: utf-8
2+
import sys
3+
4+
import rclpy
5+
from rclpy.node import Node
6+
7+
from autonomous_state_display.autonomous_state_display_core import AutonomousStateDisplay
8+
from ament_index_python.packages import get_package_share_directory
9+
10+
def main(args=None):
11+
package_path = get_package_share_directory("autonomous_state_display")
12+
13+
rclpy.init(args=args)
14+
node = Node("autonomous_state_display")
15+
16+
autonomous_state_display = AutonomousStateDisplay(node)
17+
18+
while True:
19+
rclpy.spin_once(node, timeout_sec=0.01)
20+
21+
22+
if __name__ == "__main__":
23+
main()
Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
from dataclasses import dataclass
2+
import datetime
3+
import time
4+
import serial
5+
import json
6+
import os
7+
import uuid
8+
import rclpy
9+
from std_srvs.srv import SetBool
10+
from std_msgs.msg import Bool
11+
from ament_index_python.packages import get_package_share_directory
12+
from autoware_adapi_v1_msgs.msg import MrmState, OperationModeState
13+
from std_msgs.msg import String
14+
from level4_mode_manager_msgs.msg import Level4DrivingStatus
15+
import subprocess
16+
17+
class AutonomousStateDisplay:
18+
def __init__(self, node):
19+
self.node = node
20+
21+
self.autoware_status = {
22+
"driving": False,
23+
"mrm": False,
24+
}
25+
self.is_autoware_launch = False
26+
27+
# ros interface
28+
api_qos = rclpy.qos.QoSProfile(
29+
history=rclpy.qos.QoSHistoryPolicy.KEEP_LAST,
30+
depth=10,
31+
reliability=rclpy.qos.QoSReliabilityPolicy.RELIABLE,
32+
durability=rclpy.qos.QoSDurabilityPolicy.TRANSIENT_LOCAL,
33+
)
34+
35+
node.create_service(SetBool, "/signage/trigger_external", self.trigger_external_signage)
36+
node.create_service(SetBool, "/signage/mode_change", self.change_mode)
37+
node.create_service(SetBool, "/signage/airport_mode_change", self.change_airport_mode)
38+
self.mode_status_pub_ = node.create_publisher(Bool, "/signage/mode_status", api_qos)
39+
self.setting_pub_ = node.create_publisher(String, "/signage/external/settings", api_qos)
40+
self._sub_mrm = node.create_subscription(
41+
MrmState,
42+
"/api/fail_safe/mrm_state",
43+
self.sub_mrm_callback,
44+
api_qos,
45+
)
46+
self._sub_operation_mode = node.create_subscription(
47+
OperationModeState,
48+
"/api/operation_mode/state",
49+
self.sub_operation_mode_callback,
50+
api_qos,
51+
)
52+
self._sub_is_driving_level = node.create_subscription(
53+
Level4DrivingStatus,
54+
"/level4_mode_manager/is_level4_driving",
55+
self.sub_is_driving_level,
56+
api_qos,
57+
)
58+
59+
# read settings.If not, creatte settings.
60+
self._settings_file = "/home/" + os.environ.get("USER") + "/settings.json"
61+
if os.path.exists(self._settings_file):
62+
with open(self._settings_file, "r") as f:
63+
self._settings = json.load(f)
64+
else:
65+
self._settings = {"in_experiment": True, "airport": False}
66+
with open(self._settings_file, "w") as f:
67+
json.dump(self._settings, f, indent=4)
68+
69+
# initial display 何も表示しない
70+
self.display_signage("null", True)
71+
72+
# 状態出力するタイマー
73+
self.timer = node.create_timer(1, self.pub_setting)
74+
75+
def pub_setting(self):
76+
setting = json.dumps(self._settings)
77+
msg = String()
78+
msg.data = setting
79+
self.setting_pub_.publish(msg)
80+
81+
def pub_mode_status(self, status):
82+
msg = Bool()
83+
msg.data = status
84+
self.mode_status_pub_.publish(msg)
85+
86+
def send_data(self, data_key):
87+
command_data = []
88+
self.node.get_logger().info(str(data_key))
89+
if data_key == "auto":
90+
command_data = ["sudo", "i2cset", "-y", "0", "0x40", "0x01", "0x07"]
91+
elif data_key == "mrm":
92+
command_data = ["sudo", "i2cset", "-y", "0", "0x40", "0x01", "0x01"]
93+
elif data_key == "experiment":
94+
command_data = ["sudo", "i2cset", "-y", "0", "0x40", "0x01", "0x03"]
95+
elif data_key == "null":
96+
command_data = ["sudo", "i2cset", "-y", "0", "0x40", "0x01", "0x00"]
97+
98+
self.node.get_logger().info(str(command_data))
99+
command_data = ["sudo", "ls", "/home/makotoyabuta"]
100+
101+
if len(command_data) == 0:
102+
return
103+
result = subprocess.run(
104+
command_data,
105+
capture_output=True,
106+
text=True
107+
)
108+
109+
self.node.get_logger().info(str(result.stdout))
110+
self.node.get_logger().info(str(result.stderr))
111+
self.node.get_logger().info(str(result.returncode))
112+
113+
114+
# 出力コマンド一覧
115+
# sudo i2cset -y 0 0x40 0x01 0x00 #空欄
116+
# sudo i2cset -y 0 0x40 0x01 0x01 #緊急停止中
117+
# sudo i2cset -y 0 0x40 0x01 0x02 #乗降中
118+
# sudo i2cset -y 0 0x40 0x01 0x03 #実証実験中
119+
# sudo i2cset -y 0 0x40 0x01 0x04 #SOS
120+
# sudo i2cset -y 0 0x40 0x01 0x05 #低速走行中
121+
# sudo i2cset -y 0 0x40 0x01 0x06 #回送中
122+
# sudo i2cset -y 0 0x40 0x01 0x07 #自動運行中
123+
124+
125+
126+
127+
# Lv4のときは自動運転中かどうかで表示を変更する。Lv2のときは「実験中」を固定で表示する
128+
def trigger_external_signage(self, request, response):
129+
try:
130+
# operation modeが変わったときにautowareが起動したと判断する
131+
self.autoware_status ["driving"] = request.data
132+
if self._settings["in_experiment"]:
133+
self.display_signage("experiment")
134+
return response
135+
elif self._settings["airport"]:
136+
if self.autoware_status["mrm"]:
137+
self.display_signage("mrm")
138+
else:
139+
if request.data:
140+
self.display_signage("auto")
141+
else:
142+
self.display_signage("null")
143+
else:
144+
if request.data:
145+
self.display_signage("auto")
146+
else:
147+
self.display_signage("null")
148+
response.success = True
149+
except Exception as e:
150+
self.node.get_logger().error(str(e))
151+
return response
152+
153+
# MRMが発生していて空港モードの場合は「緊急停止中」表示にする
154+
def sub_mrm_callback(self, msg):
155+
try:
156+
if self._settings["in_experiment"]:
157+
return
158+
self.autoware_status["mrm"] = msg.state in [2,3,4]
159+
if self._settings["airport"] and self.autoware_status["mrm"]:
160+
self.display_signage("mrm")
161+
else:
162+
if self.autoware_status["driving"]:
163+
self.display_signage("auto")
164+
else:
165+
self.display_signage("null")
166+
except Exception as e:
167+
self.node.get_logger().error("Unable to get the mrm, ERROR: " + str(e))
168+
169+
# operation modeを受け取ったとき起動したと判断する
170+
def sub_operation_mode_callback(self, msg):
171+
try:
172+
# operation modeが変わったときにautowareが起動したと判断する
173+
self.is_autoware_launch = True
174+
self.node.get_logger().info(str(msg.data))
175+
except Exception as e:
176+
self.node.get_logger().error("Unable to get the operation mode, ERROR: " + str(e))
177+
178+
# l4かどうかのtopicを受け取り走行モードを変更する
179+
def sub_is_driving_level(self, msg):
180+
try:
181+
self.node.get_logger().info(str(msg.is_level4_driving))
182+
if msg.is_level4_driving: # True is L4, False is L2.
183+
self.pub_mode_status(True)
184+
self._settings["in_experiment"] = False
185+
if self.autoware_status["driving"]:
186+
self.display_signage("auto")
187+
else:
188+
self.display_signage("null")
189+
else:
190+
self.pub_mode_status(False)
191+
self._settings["in_experiment"] = True
192+
self.display_signage("experiment")
193+
194+
with open(self._settings_file, "w") as f:
195+
json.dump(self._settings, f, indent=4)
196+
except Exception as e:
197+
self.node.get_logger().error(str(e))
198+
199+
# l4かどうかのサービスを受け取り走行モードを変更する
200+
def change_mode(self, request, response):
201+
try:
202+
if request.data: # True is L2, False is L4.
203+
self.pub_mode_status(True)
204+
self._settings["in_experiment"] = True
205+
self.display_signage("experiment")
206+
else:
207+
self.pub_mode_status(False)
208+
self._settings["in_experiment"] = False
209+
self.display_signage("null")
210+
211+
with open(self._settings_file, "w") as f:
212+
json.dump(self._settings, f, indent=4)
213+
response.success = True
214+
except Exception as e:
215+
self.node.get_logger().error(str(e))
216+
response.success = False
217+
return response
218+
219+
# 空港モードにするかどうかのトピックを受け取り空港モードを変更する
220+
def change_airport_mode(self, request, response):
221+
try:
222+
if request.data:
223+
self._settings["airport"] = True
224+
else:
225+
self._settings["airport"] = False
226+
with open(self._settings_file, "w") as f:
227+
json.dump(self._settings, f, indent=4)
228+
response.success = True
229+
except Exception as e:
230+
self.node.get_logger().error(str(e))
231+
response.success = False
232+
return response
233+
234+
235+
def display_signage(self, display_file, force=False):
236+
# 車外サイネージが準備中かautowareが起動してない場合は表示を変更しない。forceフラグがあるときはautowareの起動関係なく更新する
237+
if not self.is_autoware_launch and not force:
238+
return
239+
240+
self.send_data(display_file)

src/level4_mode_manager_msgs/CMakeLists.txt

Lines changed: 0 additions & 22 deletions
This file was deleted.

src/level4_mode_manager_msgs/msg/Level4Availability.msg

Lines changed: 0 additions & 2 deletions
This file was deleted.

src/level4_mode_manager_msgs/msg/Level4DrivingStatus.msg

Lines changed: 0 additions & 2 deletions
This file was deleted.

0 commit comments

Comments
 (0)