提交 5c0fc89b 编写于 作者: A Aaron Xiao 提交者: Jiangtao Hu

HMI: Backward compatible to Apollo 1.0.

上级 ce069510
...@@ -56,8 +56,8 @@ message ToolStatus { ...@@ -56,8 +56,8 @@ message ToolStatus {
} }
message ConfigStatus { message ConfigStatus {
optional string current_map = 1 [default = "Unknown"]; optional string current_map = 1;
optional string current_vehicle = 2 [default = "Unknown"]; optional string current_vehicle = 2;
} }
message RuntimeStatus { message RuntimeStatus {
......
...@@ -35,6 +35,8 @@ class Config(object): ...@@ -35,6 +35,8 @@ class Config(object):
pb_singleton = None pb_singleton = None
apollo_root = os.path.join(os.path.dirname(__file__), '../../..') apollo_root = os.path.join(os.path.dirname(__file__), '../../..')
log = logging.getLogger('HMI') log = logging.getLogger('HMI')
record_replay_required_modules = [
'GPS', 'control', 'canbus', 'localization', 'dreamview', 'record_bag']
@classmethod @classmethod
def get_pb(cls): def get_pb(cls):
......
...@@ -26,7 +26,7 @@ import system_cmd ...@@ -26,7 +26,7 @@ import system_cmd
class ModuleApi(object): class ModuleApi(object):
""" """
Module SocketIO API: Module SocketIO API:
start [all | <module>] start [all | record_replay | <module>]
stop [all | <module>] stop [all | <module>]
""" """
...@@ -53,7 +53,11 @@ class ModuleApi(object): ...@@ -53,7 +53,11 @@ class ModuleApi(object):
system_cmd.async_run_command_pb(cmd) system_cmd.async_run_command_pb(cmd)
if module_name == 'all': if module_name == 'all':
_ = [__single_start(conf.name) for conf in Config.get_pb().modules] for conf in Config.get_pb().modules:
__single_start(conf.name)
elif module_name == 'record_replay_required_modules':
for mod in Config.record_replay_required_modules:
__single_start(mod)
else: else:
__single_start(module_name) __single_start(module_name)
RuntimeStatus.broadcast_status_if_changed() RuntimeStatus.broadcast_status_if_changed()
......
...@@ -37,9 +37,6 @@ class RuntimeStatus(object): ...@@ -37,9 +37,6 @@ class RuntimeStatus(object):
pb_singleton = runtime_status_pb2.RuntimeStatus() pb_singleton = runtime_status_pb2.RuntimeStatus()
pb_fingerprint = 0 pb_fingerprint = 0
module_dict = {}
hardware_dict = {}
playable_duration = 0 playable_duration = 0
@classmethod @classmethod
...@@ -47,8 +44,6 @@ class RuntimeStatus(object): ...@@ -47,8 +44,6 @@ class RuntimeStatus(object):
"""Reset runtime status to start.""" """Reset runtime status to start."""
cls.pb_singleton.Clear() cls.pb_singleton.Clear()
cls.pb_fingerprint = 0 cls.pb_fingerprint = 0
cls.module_dict.clear()
cls.hardware_dict.clear()
tool_status = cls.get_tools() tool_status = cls.get_tools()
if check_playable_file and cls.stat_playable_duration() > 0: if check_playable_file and cls.stat_playable_duration() > 0:
...@@ -77,20 +72,16 @@ class RuntimeStatus(object): ...@@ -77,20 +72,16 @@ class RuntimeStatus(object):
@classmethod @classmethod
def get_module(cls, module_name): def get_module(cls, module_name):
"""Get module status by name.""" """Get module status by name."""
if cls.module_dict.get(module_name) is None: mod = cls.__find_by_name(module_name, cls.pb_singleton.modules)
# Init module status for once. # Init module status if not exist.
module_status = cls.pb_singleton.modules.add(name=module_name) return mod if mod else cls.pb_singleton.modules.add(name=module_name)
cls.module_dict[module_name] = module_status
return cls.module_dict[module_name]
@classmethod @classmethod
def get_hardware(cls, hardware_name): def get_hardware(cls, hardware_name):
"""Get harware status by name.""" """Get hardware status by name."""
if cls.hardware_dict.get(hardware_name) is None: hdw = cls.__find_by_name(hardware_name, cls.pb_singleton.hardware)
# Init hardware status for once. # Init hardware status for once.
hardware_status = cls.pb_singleton.hardware.add(name=hardware_name) return hdw if hdw else cls.pb_singleton.hardware.add(name=hardware_name)
cls.hardware_dict[hardware_name] = hardware_status
return cls.hardware_dict[hardware_name]
@classmethod @classmethod
def get_tools(cls): def get_tools(cls):
...@@ -100,26 +91,10 @@ class RuntimeStatus(object): ...@@ -100,26 +91,10 @@ class RuntimeStatus(object):
@classmethod @classmethod
def status_json(cls): def status_json(cls):
"""Convert status to json dict.""" """Convert status to json dict."""
json_dict = json_format.MessageToDict(cls.pb_singleton, True, True)
def pb_to_json(proto, include_default_values=False): # Inject current timestamp.
"""Convert proto to json dict.""" json_dict['timestamp'] = cls._current_timestamp()
return json_format.MessageToDict( return json_dict
proto, include_default_values, True)
def pb_dict_to_json(pb_dict):
"""Convert {key: value_pb} to {key, value_dict}."""
return {
key: pb_to_json(value_pb)
for key, value_pb in pb_dict.iteritems()
}
return {
'timestamp': cls._current_timestamp(),
'modules': pb_dict_to_json(cls.module_dict),
'hardware': pb_dict_to_json(cls.hardware_dict),
'tools': pb_to_json(cls.pb_singleton.tools, True),
'config': pb_to_json(cls.pb_singleton.config, True),
}
@classmethod @classmethod
def broadcast_status_if_changed(cls): def broadcast_status_if_changed(cls):
...@@ -134,17 +109,17 @@ class RuntimeStatus(object): ...@@ -134,17 +109,17 @@ class RuntimeStatus(object):
@classmethod @classmethod
def _calculate(cls): def _calculate(cls):
"""Update runtime status fields which need to be calculated.""" """Update runtime status fields which need to be calculated."""
modules_and_hardware_ready = cls.are_all_modules_ready( modules_and_hardware_ready = cls.are_record_replay_modules_ready(
) and cls.are_all_hardware_ready() ) and cls.are_all_hardware_ready()
cls._calculate_recording_status(modules_and_hardware_ready) cls._calculate_recording_status(modules_and_hardware_ready)
cls._calculate_playing_status(modules_and_hardware_ready) cls._calculate_playing_status(modules_and_hardware_ready)
cls._calculate_guide_message() cls._calculate_guide_message()
@classmethod @classmethod
def are_all_modules_ready(cls): def are_record_replay_modules_ready(cls):
"""Check if all modules are ready.""" """Check if all modules are ready."""
for mod in Config.get_pb().modules: for mod in Config.record_replay_required_modules:
mod_status = cls.get_module(mod.name).status mod_status = cls.get_module(mod).status
if mod_status != runtime_status_pb2.ModuleStatus.STARTED: if mod_status != runtime_status_pb2.ModuleStatus.STARTED:
return False return False
return True return True
...@@ -251,3 +226,8 @@ class RuntimeStatus(object): ...@@ -251,3 +226,8 @@ class RuntimeStatus(object):
def _current_timestamp(cls): def _current_timestamp(cls):
"""Current timestamp in milliseconds.""" """Current timestamp in milliseconds."""
return int(time.time() * 1000) return int(time.time() * 1000)
@staticmethod
def __find_by_name(name, value_list):
"""Find a value in list by name."""
return next((value for value in value_list if value.name == name), None)
...@@ -69,18 +69,11 @@ ...@@ -69,18 +69,11 @@
// Change UI according to status. // Change UI according to status.
function on_modules_status_change(global_status) { function on_modules_status_change(global_status) {
var modules = [{% for module in conf_pb.modules %} '{{ module.name }}', {% endfor %}]; global_status['modules'].forEach(function(module_status) {
modules.forEach(function(module_name) {
// Get module status. // Get module status.
status_code = 'UNINITIALIZED'; status_code = 'status' in module_status ? module_status['status']
if (module_name in global_status['modules']) { : 'UNINITIALIZED';
module_status = global_status['modules'][module_name]; $btn = $("#module_" + module_status['name'] + " .module_switch");
if ('status' in module_status) {
status_code = module_status['status'];
}
}
$btn = $("#module_" + module_name + " .module_switch");
if (status_code == 'STARTED' || status_code == 'INITIALIZED') { if (status_code == 'STARTED' || status_code == 'INITIALIZED') {
$btn.removeClass("module_switch_close").addClass("module_switch_open"); $btn.removeClass("module_switch_close").addClass("module_switch_open");
} else { } else {
......
...@@ -162,17 +162,10 @@ ...@@ -162,17 +162,10 @@
<script> <script>
// Change UI according to status. // Change UI according to status.
function on_hardware_status_change(global_status) { function on_hardware_status_change(global_status) {
var hw_list = [{% for hw in conf_pb.hardware %} '{{ hw.name }}', {% endfor %}]; global_status['hardware'].forEach(function(hw_status) {
hw_list.forEach(function(hw_name) { status_code = 'status' in hw_status ? hw_status['status'] : undefined;
var status_code = undefined;
if (hw_name in global_status['hardware']) {
hw_status = global_status['hardware'][hw_name];
if ('status' in hw_status) {
status_code = hw_status['status'];
}
}
$glyphicon = $("#hardware_" + hw_name + " .glyphicon"); $glyphicon = $("#hardware_" + hw_status['name'] + " .glyphicon");
$glyphicon.attr("class", "glyphicon"); $glyphicon.attr("class", "glyphicon");
if (status_code == undefined || status_code == -1) { if (status_code == undefined || status_code == -1) {
return; return;
...@@ -196,13 +189,21 @@ ...@@ -196,13 +189,21 @@
function on_config_status_change(global_status) { function on_config_status_change(global_status) {
// Config status change. // Config status change.
var current_map = global_status['config']['current_map']; var current_map = undefined;
var current_vehicle = global_status['config']['current_vehicle']; var current_vehicle = undefined;
$('.current_map').text( if ('config' in global_status) {
current_map != 'Unknown' ? current_map : 'Please select'); if ('current_map' in global_status['config']) {
$('.current_vehicle').text( current_map = global_status['config']['current_map'];
current_vehicle != 'Unknown' ? current_vehicle : 'Please select'); }
if (current_map == 'Unknown' || current_vehicle == 'Unknown') { if ('current_vehicle' in global_status['config']) {
current_vehicle = global_status['config']['current_vehicle'];
}
}
const kTextEmpty = 'Please select';
$('.current_map').text(current_map ? current_map : kTextEmpty);
$('.current_vehicle').text(current_vehicle ? current_vehicle : kTextEmpty);
if (!current_map || !current_vehicle) {
// Show profile dialog if map or vehicle is not selected. // Show profile dialog if map or vehicle is not selected.
$("#profile_dialog").modal(); $("#profile_dialog").modal();
} }
......
...@@ -44,31 +44,33 @@ class ToolApi(object): ...@@ -44,31 +44,33 @@ class ToolApi(object):
reset_all reset_all
switch_map switch_map
""" """
tools_status = RuntimeStatus.get_tools()
@classmethod @classmethod
def setup_recording(cls): def setup_recording(cls):
"""SocketIO Api: setup_recording()""" """SocketIO Api: setup_recording()"""
if not RuntimeStatus.are_all_modules_ready(): if not RuntimeStatus.are_record_replay_modules_ready():
ModuleApi.start('all') ModuleApi.start('record_replay_required_modules')
if not RuntimeStatus.are_all_hardware_ready(): if not RuntimeStatus.are_all_hardware_ready():
HardwareApi.health_check('all') HardwareApi.health_check('all')
cls.tools_status.recording_status = ToolStatus.RECORDING_CHECKING RuntimeStatus.get_tools().recording_status = (
ToolStatus.RECORDING_CHECKING)
RuntimeStatus.broadcast_status_if_changed() RuntimeStatus.broadcast_status_if_changed()
@classmethod @classmethod
def start_recording(cls): def start_recording(cls):
"""SocketIO Api: start_recording()""" """SocketIO Api: start_recording()"""
cls.__exec_bash_tool('start_recording') cls.__exec_bash_tool('start_recording')
cls.tools_status.recording_status = ToolStatus.RECORDING tool_status = RuntimeStatus.get_tools()
cls.tools_status.playing_status = ToolStatus.PLAYING_NOT_READY tool_status.recording_status = ToolStatus.RECORDING
tool_status.playing_status = ToolStatus.PLAYING_NOT_READY
RuntimeStatus.broadcast_status_if_changed() RuntimeStatus.broadcast_status_if_changed()
@classmethod @classmethod
def stop_recording(cls): def stop_recording(cls):
"""SocketIO Api: stop_recording()""" """SocketIO Api: stop_recording()"""
cls.__exec_bash_tool('stop_recording') cls.__exec_bash_tool('stop_recording')
cls.tools_status.recording_status = ToolStatus.RECORDING_FINISHED RuntimeStatus.get_tools().recording_status = (
ToolStatus.RECORDING_FINISHED)
RuntimeStatus.stat_playable_duration() RuntimeStatus.stat_playable_duration()
@classmethod @classmethod
...@@ -79,27 +81,28 @@ class ToolApi(object): ...@@ -79,27 +81,28 @@ class ToolApi(object):
os.rename(file_to_play, file_to_play + '.bak') os.rename(file_to_play, file_to_play + '.bak')
# Also stop player in case user has set it up. # Also stop player in case user has set it up.
cls.__exec_bash_tool('stop_player') cls.__exec_bash_tool('stop_player')
cls.tools_status.recording_status = ToolStatus.RECORDING_READY_TO_CHECK tool_status = RuntimeStatus.get_tools()
cls.tools_status.playing_status = ToolStatus.PLAYING_NOT_READY Rtool_status.recording_status = ToolStatus.RECORDING_READY_TO_CHECK
cls.tools_status.planning_ready = False tool_status.playing_status = ToolStatus.PLAYING_NOT_READY
tool_status.planning_ready = False
RuntimeStatus.broadcast_status_if_changed() RuntimeStatus.broadcast_status_if_changed()
@classmethod @classmethod
def setup_playing(cls): def setup_playing(cls):
"""SocketIO Api: setup_playing()""" """SocketIO Api: setup_playing()"""
if not RuntimeStatus.are_all_modules_ready(): if not RuntimeStatus.are_record_replay_modules_ready():
ModuleApi.start('all') ModuleApi.start('record_replay_required_modules')
if not RuntimeStatus.are_all_hardware_ready(): if not RuntimeStatus.are_all_hardware_ready():
HardwareApi.health_check('all') HardwareApi.health_check('all')
cls.__exec_bash_tool('start_player') cls.__exec_bash_tool('start_player')
cls.tools_status.playing_status = ToolStatus.PLAYING_CHECKING RuntimeStatus.get_tools().playing_status = ToolStatus.PLAYING_CHECKING
RuntimeStatus.broadcast_status_if_changed() RuntimeStatus.broadcast_status_if_changed()
@classmethod @classmethod
def start_playing(cls): def start_playing(cls):
"""SocketIO Api: start_playing()""" """SocketIO Api: start_playing()"""
RosBridgeApi.change_driving_mode('auto') RosBridgeApi.change_driving_mode('auto')
cls.tools_status.playing_status = ToolStatus.PLAYING RuntimeStatus.get_tools().playing_status = ToolStatus.PLAYING
RuntimeStatus.broadcast_status_if_changed() RuntimeStatus.broadcast_status_if_changed()
@classmethod @classmethod
...@@ -107,8 +110,9 @@ class ToolApi(object): ...@@ -107,8 +110,9 @@ class ToolApi(object):
"""SocketIO Api: stop_playing()""" """SocketIO Api: stop_playing()"""
RosBridgeApi.change_driving_mode('manual') RosBridgeApi.change_driving_mode('manual')
cls.__exec_bash_tool('stop_player') cls.__exec_bash_tool('stop_player')
cls.tools_status.playing_status = ToolStatus.PLAYING_READY_TO_CHECK tool_status = RuntimeStatus.get_tools()
cls.tools_status.planning_ready = False tool_status.playing_status = ToolStatus.PLAYING_READY_TO_CHECK
tool_status.planning_ready = False
RuntimeStatus.broadcast_status_if_changed() RuntimeStatus.broadcast_status_if_changed()
@classmethod @classmethod
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册