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

HMI: Backward compatible to Apollo 1.0.

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