From 7e55339bb6588849816088cfb7bdc16c43d79f8c Mon Sep 17 00:00:00 2001 From: aibingbing Date: Thu, 25 Aug 2022 21:42:52 +0800 Subject: [PATCH] =?UTF-8?q?[=E6=B8=85=E6=89=AB=E8=BD=A6]feat:=20=E6=B8=85?= =?UTF-8?q?=E6=89=AB=E8=BD=A6=E5=90=84=E6=8E=A7=E5=88=B6=E9=9D=A2=E6=9D=BF?= =?UTF-8?q?=E4=B8=AD=E6=8C=89=E9=92=AE=E7=82=B9=E5=87=BB=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E5=8F=8A=E7=9B=B8=E5=85=B3=E9=80=BB=E8=BE=91=E5=A4=84=E7=90=86?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sweeper/ui/SweeperOperatePanelView.java | 709 +++++++++++++++--- .../sweeper/util/SweeperFutianCmdUtil.java | 52 +- ...sweeper_operate_panel_btn1_bg_selector.xml | 4 +- ...sweeper_operate_panel_btn2_bg_selector.xml | 6 +- .../res/layout/sweeper_operate_panel_view.xml | 76 +- 5 files changed, 692 insertions(+), 155 deletions(-) diff --git a/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/ui/SweeperOperatePanelView.java b/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/ui/SweeperOperatePanelView.java index e2cc174570..1b40a8f95f 100644 --- a/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/ui/SweeperOperatePanelView.java +++ b/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/ui/SweeperOperatePanelView.java @@ -1,16 +1,30 @@ package com.mogo.och.sweeper.ui; +import static com.mogo.och.sweeper.util.SweeperFutianCmdUtil.CLEAN_DIRECTION_BOTH_SIDE; +import static com.mogo.och.sweeper.util.SweeperFutianCmdUtil.CLEAN_DIRECTION_LEFT_SIDE; +import static com.mogo.och.sweeper.util.SweeperFutianCmdUtil.CLEAN_DIRECTION_RIGHT_SIDE; +import static com.mogo.och.sweeper.util.SweeperFutianCmdUtil.CLEAN_INTENSITY_STRAND; +import static com.mogo.och.sweeper.util.SweeperFutianCmdUtil.CLEAN_INTENSITY_STRONG; +import static com.mogo.och.sweeper.util.SweeperFutianCmdUtil.CLEAN_MODE_PURE_DRAW; +import static com.mogo.och.sweeper.util.SweeperFutianCmdUtil.CLEAN_MODE_PURE_SWEEP; +import static com.mogo.och.sweeper.util.SweeperFutianCmdUtil.CLEAN_MODE_PURE_WASH; +import static com.mogo.och.sweeper.util.SweeperFutianCmdUtil.CLEAN_MODE_WASH_SWEEP; + import android.content.Context; +import android.content.DialogInterface; import android.os.Handler; import android.os.Message; import android.util.AttributeSet; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; +import android.widget.CheckedTextView; import android.widget.LinearLayout; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotVehicleStateListener; import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotManager; @@ -19,6 +33,11 @@ import com.mogo.eagle.core.utilcode.util.ThreadUtils; import com.mogo.eagle.core.utilcode.util.ToastUtils; import com.mogo.module.common.view.OnPreventFastClickListener; import com.mogo.och.sweeper.R; +import com.mogo.och.sweeper.util.SweeperFutianCmdUtil; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; import chassis.Chassis; import chassis.SpecialVehicleTaskCmdOuterClass; @@ -27,25 +46,71 @@ import chassis.VehicleStateOuterClass; /** * 清扫车操作面板View */ -public class SweeperOperatePanelView extends LinearLayout{ +public class SweeperOperatePanelView extends LinearLayout { private static final String TAG = "SweeperOperatePanelView"; private static final int CMD_EXECUTE_TIMEOUT_SECONDS = 5; + private static final int CMD_EXECUTE_MOCK_SUCCESS_SECONDS = 3; - TextView mBtnMainSwitchOpenClose;//开关 - TextView mBtnOperateModePureSweep;//纯扫 - TextView mBtnOperateModePureWash;//纯洗 - TextView mBtnOperateModeSweepWash;//洗扫 - TextView mBtnOperateModePureAbsorption;//纯吸 - TextView mBtnCleanDirectionLeftSide;//左侧 - TextView mBtnCleanDirectionRightSide;//右侧 - TextView mBtnCleanDirectionBothSide;//两侧 - TextView mBtnCleanIntensityStandard;//普通 - TextView mBtnCleanIntensityStrong;//强力 + CheckedTextView mBtnCleanWorkOpenClose;//开关 + CheckedTextView mBtnCleanModePureSweep;//纯扫 + CheckedTextView mBtnCleanModePureWash;//纯洗 + CheckedTextView mBtnCleanModeSweepWash;//洗扫 + CheckedTextView mBtnCleanModePureAbsorption;//纯吸 + CheckedTextView mBtnCleanDirectionLeftSide;//左侧 + CheckedTextView mBtnCleanDirectionRightSide;//右侧 + CheckedTextView mBtnCleanDirectionBothSide;//两侧 + CheckedTextView mBtnCleanIntensityStandard;//普通 + CheckedTextView mBtnCleanIntensityStrong;//强力 LinearLayout mLoadingContainer;//loading container TextView mLoadingHintTop;//loading 提示-上面 TextView mLoadingHintBottom;//loading 提示-下面 + // 作业模式相关操作按钮的id + List cleanModeBtnViewIds = Arrays.asList( + R.id.btn_clean_mode_pure_sweep, + R.id.btn_clean_mode_pure_wash, + R.id.btn_clean_mode_sweep_wash, + R.id.btn_clean_mode_pure_absorption); + + // 作业模式相关操作按钮,对应命令参数值 + HashMap cleanModeBtnAndCmdValueMap = new HashMap() { + { + put(R.id.btn_clean_mode_pure_sweep, CLEAN_MODE_PURE_SWEEP); + put(R.id.btn_clean_mode_pure_wash, CLEAN_MODE_PURE_WASH); + put(R.id.btn_clean_mode_sweep_wash, CLEAN_MODE_WASH_SWEEP); + put(R.id.btn_clean_mode_pure_absorption, CLEAN_MODE_PURE_DRAW); + } + }; + + // 清扫方向相关操作按钮的id + List cleanDirectionBtnViewIds = Arrays.asList( + R.id.btn_clean_direction_left_side, + R.id.btn_clean_direction_right_side, + R.id.btn_clean_direction_both_side); + + // 清扫方向相关按钮操作,对应命令参数值 + HashMap cleanDirectionBtnAndCmdValueMap = new HashMap() { + { + put(R.id.btn_clean_direction_left_side, CLEAN_DIRECTION_LEFT_SIDE); + put(R.id.btn_clean_direction_right_side, CLEAN_DIRECTION_RIGHT_SIDE); + put(R.id.btn_clean_direction_both_side, CLEAN_DIRECTION_BOTH_SIDE); + } + }; + + // 作业强度相关按钮操作 + List cleanIntensityBtnViewIds = Arrays.asList( + R.id.btn_clean_intensity_standard, + R.id.btn_clean_intensity_strong); + + // 作业强度相关按钮操作,对应命令参数值 + HashMap cleanIntensityBtnAndCmdValueMap = new HashMap() { + { + put(R.id.btn_clean_intensity_standard, CLEAN_INTENSITY_STRAND); + put(R.id.btn_clean_intensity_strong, CLEAN_INTENSITY_STRONG); + } + }; + public SweeperOperatePanelView(Context context) { super(context); } @@ -67,16 +132,16 @@ public class SweeperOperatePanelView extends LinearLayout{ private void initView(Context context) { LayoutInflater.from(context).inflate(R.layout.sweeper_operate_panel_view, this, true); - mBtnMainSwitchOpenClose = findViewById(R.id.btn_main_switch_open_close); - mBtnOperateModePureSweep = findViewById(R.id.btn_operate_mode_pure_sweep); - mBtnOperateModePureWash = findViewById(R.id.btn_operate_mode_pure_wash); - mBtnOperateModeSweepWash = findViewById(R.id.btn_operate_mode_sweep_wash); - mBtnOperateModePureAbsorption = findViewById(R.id.btn_operate_mode_pure_absorption); - mBtnCleanDirectionLeftSide = findViewById(R.id.btn_clean_direction_left_side); - mBtnCleanDirectionRightSide = findViewById(R.id.btn_clean_direction_right_side); - mBtnCleanDirectionBothSide = findViewById(R.id.btn_clean_direction_both_side); - mBtnCleanIntensityStandard = findViewById(R.id.btn_clean_intensity_standard); - mBtnCleanIntensityStrong = findViewById(R.id.btn_clean_intensity_strong); + mBtnCleanWorkOpenClose = (CheckedTextView) findViewById(R.id.btn_clean_work_open_close); + mBtnCleanModePureSweep = (CheckedTextView) findViewById(R.id.btn_clean_mode_pure_sweep); + mBtnCleanModePureWash = (CheckedTextView) findViewById(R.id.btn_clean_mode_pure_wash); + mBtnCleanModeSweepWash = (CheckedTextView) findViewById(R.id.btn_clean_mode_sweep_wash); + mBtnCleanModePureAbsorption = (CheckedTextView) findViewById(R.id.btn_clean_mode_pure_absorption); + mBtnCleanDirectionLeftSide = (CheckedTextView) findViewById(R.id.btn_clean_direction_left_side); + mBtnCleanDirectionRightSide = (CheckedTextView) findViewById(R.id.btn_clean_direction_right_side); + mBtnCleanDirectionBothSide = (CheckedTextView) findViewById(R.id.btn_clean_direction_both_side); + mBtnCleanIntensityStandard = (CheckedTextView) findViewById(R.id.btn_clean_intensity_standard); + mBtnCleanIntensityStrong = (CheckedTextView) findViewById(R.id.btn_clean_intensity_strong); mLoadingContainer = findViewById(R.id.loading_hint_container); mLoadingHintTop = findViewById(R.id.loading_hint_top); mLoadingHintBottom = findViewById(R.id.loading_hint_bottom); @@ -84,85 +149,502 @@ public class SweeperOperatePanelView extends LinearLayout{ } private void initViewListener() { - mBtnMainSwitchOpenClose.setOnClickListener(new OnPreventFastClickListener() { + setClickListener(mBtnCleanWorkOpenClose, (v) -> onCleanWorkBtnClick()); + setClickListener(mBtnCleanModePureSweep, (v) -> onCleanModeBtnClick(v)); + setClickListener(mBtnCleanModePureWash, (v) -> onCleanModeBtnClick(v)); + setClickListener(mBtnCleanModeSweepWash, (v) -> onCleanModeBtnClick(v)); + setClickListener(mBtnCleanModePureAbsorption, (v) -> onCleanModeBtnClick(v)); + setClickListener(mBtnCleanDirectionLeftSide, (v) -> onCleanDirectionBtnClick(v)); + setClickListener(mBtnCleanDirectionRightSide, (v) -> onCleanDirectionBtnClick(v)); + setClickListener(mBtnCleanDirectionBothSide, (v) -> onCleanDirectionBtnClick(v)); + setClickListener(mBtnCleanIntensityStandard, (v) -> onCleanIntensityBtnClick(v)); + setClickListener(mBtnCleanIntensityStrong, (v) -> onCleanIntensityBtnClick(v)); + } + + /** + * 清扫任务开关按钮点击事件 + */ + private void onCleanWorkBtnClick() { + // 是否是 关闭 操作 + boolean isCloseAction = mBtnCleanWorkOpenClose.isChecked(); + CmdRequestCallback cmdRequestCallback = new CmdRequestCallback() { + @Override + public void onSendCmd() { + showLoadingMask(CMD_EXECUTE_TIMEOUT_SECONDS); + } + + @Override + public void onCountDownTick(int seconds) { + updateLoadingCountDown(seconds); + } + + @Override + public boolean onCheckIfCmdSuccess(VehicleStateOuterClass.SweeperFuTianCleanSystemState cleanSystemState) { + //TODO + return true; + } + + @Override + public void onCmdSuccess() { + if (isCloseAction) { + mBtnCleanWorkOpenClose.setText("Open"); + mBtnCleanWorkOpenClose.setChecked(false); + toggleCleanModeBtnsStatus(false); + toggleCleanDirectionBtnsStatus(false); + toggleCleanIntensityBtnsStatus(false); + } else { + mBtnCleanWorkOpenClose.setText("Close"); + mBtnCleanWorkOpenClose.setChecked(true); + toggleCleanModeBtnsStatus(true); + } + hideLoadingMask(); + showCmdExecuteSuccessToast(); + } + + @Override + public void onCmdFailed() { + } + + @Override + public void onCmdTimeout() { + //按钮样式恢复原样 + if (isCloseAction) { + mBtnCleanWorkOpenClose.setText("Close"); + mBtnCleanWorkOpenClose.setChecked(true); + } else { + mBtnCleanWorkOpenClose.setText("Open"); + mBtnCleanWorkOpenClose.setChecked(false); + } + hideLoadingMask(); + showCmdExecuteTimeoutToast(); + } + }; + if (isCloseAction) { + //关闭操作,点击时需要弹框提示确认后,关闭 + showConfirmCleanWorkCloseDialog(() -> { + sendSweeperCmd( + SweeperFutianCmdUtil.buildCleanWorkStopCmd(), + cmdRequestCallback + , CMD_EXECUTE_TIMEOUT_SECONDS); + }); + } else { + //打开操作,点击时打开 + sendSweeperCmd( + SweeperFutianCmdUtil.buildCleanWorkStartCmd(), + cmdRequestCallback, + CMD_EXECUTE_TIMEOUT_SECONDS); + } + } + + /** + * 作业模式按钮点击事件 + * + * @param currentClickView + */ + private void onCleanModeBtnClick(final View currentClickView) { + CheckedTextView currentChoosedModeBtnView = null; + for (Integer viewId : cleanModeBtnViewIds) { + CheckedTextView view = (CheckedTextView) findViewById(viewId); + if (view.isChecked()) { + currentChoosedModeBtnView = view; + break; + } + } + boolean isClickCurrentChoosedModeBtn = currentChoosedModeBtnView != null + && currentChoosedModeBtnView.getId() == currentClickView.getId(); + //是否纯吸 + boolean isPureAbsorption = currentClickView.getId() == R.id.btn_clean_mode_pure_absorption; + + CmdRequestCallback cmdRequestCallback = new CmdRequestCallback() { + @Override + public void onSendCmd() { + showLoadingMask(CMD_EXECUTE_TIMEOUT_SECONDS); + } + + @Override + public void onCountDownTick(int seconds) { + updateLoadingCountDown(seconds); + } + + @Override + public boolean onCheckIfCmdSuccess(VehicleStateOuterClass.SweeperFuTianCleanSystemState cleanSystemState) { + //TODO + return true; + } + + @Override + public void onCmdSuccess() { + ((CheckedTextView) currentClickView).setChecked(!isClickCurrentChoosedModeBtn); + toggleCleanModeBtnsByChoosedViewId(currentClickView.getId(), isClickCurrentChoosedModeBtn); + if (isClickCurrentChoosedModeBtn) { + toggleCleanDirectionBtnsStatus(false); + toggleCleanIntensityBtnsStatus(false); + } else { + // 如果是纯吸,没有设置清扫方向,同时自动设置作业强度为标准 + if (isPureAbsorption) { + toggleCleanDirectionBtnsStatus(false); + setCleanIntensityStandard(); + } else { + toggleCleanDirectionBtnsStatus(true); + toggleCleanIntensityBtnsStatus(false); + } + } + hideLoadingMask(); + showCmdExecuteSuccessToast(); + } + + @Override + public void onCmdFailed() { + } + + @Override + public void onCmdTimeout() { + ((CheckedTextView) currentClickView).setChecked(isClickCurrentChoosedModeBtn); + hideLoadingMask(); + showCmdExecuteTimeoutToast(); + } + }; + + if (isClickCurrentChoosedModeBtn) { + //当前已选择模式的按钮,取消当前模式,并关闭清扫方向 + sendSweeperCmd( + SweeperFutianCmdUtil.buildCleanModeCloseCmd(), + cmdRequestCallback, + CMD_EXECUTE_TIMEOUT_SECONDS); + } else { + //开启新的作业模式,直接发送命令(纯吸需要一并设置作业强度为标准) + int cmdValue = cleanModeBtnAndCmdValueMap.get(currentClickView.getId()); + sendSweeperCmd( + isPureAbsorption ? SweeperFutianCmdUtil.buildCleanModePureDrawCmd() + : SweeperFutianCmdUtil.buildCleanModeCmd(cmdValue), + cmdRequestCallback, + CMD_EXECUTE_TIMEOUT_SECONDS); + } + } + + private void onCleanDirectionBtnClick(final View currentClickView) { + CheckedTextView currentChoosedDirectionBtnView = null; + for (Integer viewId : cleanDirectionBtnViewIds) { + CheckedTextView view = (CheckedTextView) findViewById(viewId); + if (view.isChecked()) { + currentChoosedDirectionBtnView = view; + break; + } + } + boolean isClickCurrentChoosedDirectionBtn = currentChoosedDirectionBtnView != null + && currentChoosedDirectionBtnView.getId() == currentClickView.getId(); + + CmdRequestCallback cmdRequestCallback = new CmdRequestCallback() { + @Override + public void onSendCmd() { + showLoadingMask(CMD_EXECUTE_TIMEOUT_SECONDS); + } + + @Override + public void onCountDownTick(int seconds) { + updateLoadingCountDown(seconds); + } + + @Override + public boolean onCheckIfCmdSuccess(VehicleStateOuterClass.SweeperFuTianCleanSystemState cleanSystemState) { + //TODO + return true; + } + + @Override + public void onCmdSuccess() { + ((CheckedTextView) currentClickView).setChecked(!isClickCurrentChoosedDirectionBtn); + toggleCleanDirectionBtnsByChoosedViewId(currentClickView.getId(), isClickCurrentChoosedDirectionBtn); + if (isClickCurrentChoosedDirectionBtn) { + toggleCleanIntensityBtnsStatus(false); + } else { + toggleCleanIntensityBtnsStatus(true); + // 一并设置作业强度为标准 + setCleanIntensityStandard(); + } + hideLoadingMask(); + showCmdExecuteSuccessToast(); + } + + @Override + public void onCmdFailed() { + } + + @Override + public void onCmdTimeout() { + ((CheckedTextView) currentClickView).setChecked(isClickCurrentChoosedDirectionBtn); + hideLoadingMask(); + showCmdExecuteTimeoutToast(); + } + }; + if (isClickCurrentChoosedDirectionBtn) { + //当前已选择模式的按钮,取消当前模式,重置作业强度为标准,并置灰作业强度按钮 + sendSweeperCmd( + SweeperFutianCmdUtil.buildCleanDirectionCloseCmd(), + cmdRequestCallback, + CMD_EXECUTE_TIMEOUT_SECONDS); + } else { + //开启新的作业模式,直接发送命令(作业强度默认为标准) + int cmdValue = cleanDirectionBtnAndCmdValueMap.get(currentClickView.getId()); + sendSweeperCmd( + SweeperFutianCmdUtil.buildCleanDirectionCmd(cmdValue), + cmdRequestCallback, + CMD_EXECUTE_TIMEOUT_SECONDS); + } + } + + private void onCleanIntensityBtnClick(final View currentClickView) { + boolean isStandardBtnClick = currentClickView.getId() == R.id.btn_clean_intensity_standard; + CmdRequestCallback cmdRequestCallback = new CmdRequestCallback() { + @Override + public void onSendCmd() { + showLoadingMask(CMD_EXECUTE_TIMEOUT_SECONDS); + } + + @Override + public void onCountDownTick(int seconds) { + updateLoadingCountDown(seconds); + } + + @Override + public boolean onCheckIfCmdSuccess(VehicleStateOuterClass.SweeperFuTianCleanSystemState cleanSystemState) { + //TODO + return true; + } + + @Override + public void onCmdSuccess() { + ((CheckedTextView) currentClickView).setChecked(true); + if (isStandardBtnClick) { + setCleanIntensityStandard(); + } else { + setCleanIntensityStrong(); + } + hideLoadingMask(); + showCmdExecuteSuccessToast(); + } + + @Override + public void onCmdFailed() { + } + + @Override + public void onCmdTimeout() { + ((CheckedTextView) currentClickView).setChecked(false); + hideLoadingMask(); + showCmdExecuteTimeoutToast(); + } + }; + int cmdValue = cleanIntensityBtnAndCmdValueMap.get(currentClickView.getId()); + sendSweeperCmd( + SweeperFutianCmdUtil.buildCleanIntensityCmd(cmdValue), + cmdRequestCallback, + CMD_EXECUTE_TIMEOUT_SECONDS); + } + + /** + * 作业模式按钮状态切换-置灰/开启 按钮 + * + * @param enable + */ + private void toggleCleanModeBtnsStatus(boolean enable) { + for (Integer viewId : cleanModeBtnViewIds) { + CheckedTextView view = (CheckedTextView) findViewById(viewId); + view.setEnabled(enable); + view.setChecked(false); + } + } + + /** + * 作业模式按钮状态切换-将当前点击按钮之外的其他按钮 置灰或开启 + * + * @param choosedBtnId + * @param enable + */ + private void toggleCleanModeBtnsByChoosedViewId(int choosedBtnId, boolean enable) { + for (Integer viewId : cleanModeBtnViewIds) { + CheckedTextView view = (CheckedTextView) findViewById(viewId); + if (view.getId() != choosedBtnId) { + view.setEnabled(enable); + view.setChecked(false); + } + } + } + + /** + * 清扫方向按钮状态切换-置灰/开启 按钮 + * + * @param enable + */ + private void toggleCleanDirectionBtnsStatus(boolean enable) { + for (Integer viewId : cleanDirectionBtnViewIds) { + CheckedTextView view = (CheckedTextView) findViewById(viewId); + view.setEnabled(enable); + view.setChecked(false); + } + } + + /** + * 清扫方向按钮状态切换-将当前点击按钮之外的其他按钮 置灰或开启 + * + * @param choosedBtnId + * @param enable + */ + private void toggleCleanDirectionBtnsByChoosedViewId(int choosedBtnId, boolean enable) { + for (Integer viewId : cleanDirectionBtnViewIds) { + CheckedTextView view = (CheckedTextView) findViewById(viewId); + if (view.getId() != choosedBtnId) { + view.setEnabled(enable); + view.setChecked(false); + } + } + } + + /** + * 作业强度按钮状态切换-置灰/开启 按钮 + * + * @param enable + */ + private void toggleCleanIntensityBtnsStatus(boolean enable) { + for (Integer viewId : cleanIntensityBtnViewIds) { + CheckedTextView view = (CheckedTextView) findViewById(viewId); + view.setEnabled(enable); + view.setChecked(false); + } + } + + /** + * 设置作业强度-标准 + */ + private void setCleanIntensityStandard() { + mBtnCleanIntensityStandard.setChecked(true); + mBtnCleanIntensityStandard.setEnabled(true); + mBtnCleanIntensityStrong.setChecked(false); + mBtnCleanIntensityStrong.setEnabled(true); + } + + /** + * 设置作业强度-加强 + */ + private void setCleanIntensityStrong() { + mBtnCleanIntensityStandard.setChecked(false); + mBtnCleanIntensityStandard.setEnabled(true); + mBtnCleanIntensityStrong.setChecked(true); + mBtnCleanIntensityStrong.setEnabled(true); + } + + /** + * 发送命令后等待时,展示loading + * + * @param timeout + */ + private void showLoadingMask(int timeout) { + showLoadingMask("执行中,请稍后。。。", timeout); + } + + /** + * 发送命令后等待时,展示loading + * + * @param hint + * @param timeout + */ + private void showLoadingMask(String hint, int timeout) { + runOnUIThread(() -> { + mLoadingContainer.setVisibility(View.VISIBLE); + mLoadingHintTop.setText(hint); + mLoadingHintBottom.setText( + String.format( + getContext().getApplicationContext().getString(R.string.sweeper_operate_panel_cmd_execute_timeout), + timeout + )); + }); + } + + /** + * 隐藏loading + */ + private void hideLoadingMask() { + runOnUIThread(() -> { + mLoadingContainer.setVisibility(View.GONE); + }); + } + + /** + * 更新loading中倒计时 + * + * @param timeout + */ + private void updateLoadingCountDown(int timeout) { + runOnUIThread(() -> { + mLoadingHintBottom.setText( + String.format( + getContext().getApplicationContext().getString(R.string.sweeper_operate_panel_cmd_execute_timeout), + timeout + )); + }); + } + + /** + * 命令执行成功toast + */ + private void showCmdExecuteSuccessToast() { + ToastUtils.showLong("设备已响应,操作成功"); + } + + /** + * 命令执行超时toast + */ + private void showCmdExecuteTimeoutToast() { + ToastUtils.showLong("超时未响应,操作失败"); + } + + /** + * 关闭清扫作业时,确认操作的弹框 + * + * @param runnable + */ + private void showConfirmCleanWorkCloseDialog(Runnable runnable) { + AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); + builder.setMessage("是否关闭清扫作业?"); + builder.setCancelable(true); + builder.setPositiveButton("确认", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + runnable.run(); + dialog.dismiss(); + } + }); + builder.setNegativeButton("取消", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }); + AlertDialog dialog = builder.create(); + dialog.show(); + } + + private void runOnUIThread(Runnable runnable) { + ThreadUtils.runOnUiThread(new Runnable() { + @Override + public void run() { + runnable.run(); + } + }); + } + + private void setClickListener(View view, OnClickListener listener) { + view.setOnClickListener(new OnPreventFastClickListener() { @Override public void onClickImpl(View v) { - SpecialVehicleTaskCmdOuterClass.RoboSweeperFuTianCleanCmd.Builder builder = SpecialVehicleTaskCmdOuterClass.RoboSweeperFuTianCleanCmd.newBuilder(); - SpecialVehicleTaskCmdOuterClass.RoboSweeperFuTianCleanCmd fuTianCleanCmd = builder.build(); - SpecialVehicleTaskCmdOuterClass.RoboSweeperFuTianTaskCmd fuTianTaskCmd = SpecialVehicleTaskCmdOuterClass.RoboSweeperFuTianTaskCmd.newBuilder() - .setRoboSweeperFutianCleanCmd(fuTianCleanCmd).build(); - sendSweeperCmd(fuTianTaskCmd, new CmdRequestCallback() { - @Override - public void onSendCmd() { - showLoadingMask("命令执行中。。。", 10); - } - - @Override - public void onCountDownTick(int senonds) { - updateLoadingCountDown(senonds); - } - - @Override - public boolean onCheckIfCmdSuccess(VehicleStateOuterClass.SweeperFuTianCleanSystemState cleanSystemState) { - return false; - } - - @Override - public void onCmdSuccess() { - ToastUtils.showLong("执行成功"); - } - - @Override - public void onCmdFailed() { - - } - - @Override - public void onCmdTimeout() { - hideLoadingMask(); - } - }, 10); - } - }); - } - - private void showLoadingMask(String hint, int timeout) { - ThreadUtils.runOnUiThread(new Runnable() { - @Override - public void run() { - mLoadingContainer.setVisibility(View.VISIBLE); - mLoadingHintTop.setText(hint); - mLoadingHintBottom.setText( - String.format( - getContext().getApplicationContext().getString(R.string.sweeper_operate_panel_cmd_execute_timeout), - timeout - )); - } - }); - } - - private void hideLoadingMask() { - ThreadUtils.runOnUiThread(new Runnable() { - @Override - public void run() { - mLoadingContainer.setVisibility(View.GONE); - } - }); - } - - private void updateLoadingCountDown(int timeout) { - ThreadUtils.runOnUiThread(new Runnable() { - @Override - public void run() { - mLoadingHintBottom.setText( - String.format( - getContext().getApplicationContext().getString(R.string.sweeper_operate_panel_cmd_execute_timeout), - timeout - )); + listener.onClick(v); } }); } + /** + * 底盘数据透传listener + */ private final IMoGoAutopilotVehicleStateListener mIMoGoAutopilotVehicleStateListener = new IMoGoAutopilotVehicleStateListener() { @Override public void onAutopilotDataException(long timestamp) { @@ -221,7 +703,7 @@ public class SweeperOperatePanelView extends LinearLayout{ } /** - * 发送清扫车作业命令 + * 发送清扫车相关作业命令 * * @param fuTianCleanCmd * @param cmdRequestCallback @@ -237,17 +719,41 @@ public class SweeperOperatePanelView extends LinearLayout{ mCurrentCmdRequestCallback.onSendCmd(); // 发送命令 CallerAutoPilotManager.INSTANCE.sendSweeperFuTianTaskCmd(fuTianCleanCmd); + // log发送命令 + logSweeperCmdValue(fuTianCleanCmd); // 开启倒计时 Message msg = Message.obtain(); msg.what = MSG_CMD_EXECUTE_COUNT_DOWN; msg.obj = timeout; mSweeperOperateCmdHandler.sendMessage(msg); + // Mock Cmd Success + Message successMsg = Message.obtain(); + successMsg.what = MSG_CMD_EXECUTE_MOCK_SUCCESS; + mSweeperOperateCmdHandler.sendMessageDelayed(successMsg, 1000L * CMD_EXECUTE_MOCK_SUCCESS_SECONDS); + } + + private void logSweeperCmdValue(SpecialVehicleTaskCmdOuterClass.RoboSweeperFuTianTaskCmd taskCmd) { + SpecialVehicleTaskCmdOuterClass.RoboSweeperFuTianCleanCmd roboSweeperFutianCleanCmd = taskCmd.getRoboSweeperFutianCleanCmd(); + int clean_open_requirement = roboSweeperFutianCleanCmd.getCleanOpenRequirement(); + int clean_mode_requirement = roboSweeperFutianCleanCmd.getCleanModeRequirement(); + int clean_direction_requirement = roboSweeperFutianCleanCmd.getCleanDirectionRequirement(); + int clean_intensity_requirement = roboSweeperFutianCleanCmd.getCleanIntensityRequirement(); + Log.d(TAG, "---- sendSweeperFuTianTaskCmd ----" + + "[clean_open_requirement = " + clean_open_requirement + "]," + + "[clean_mode_requirement = " + clean_mode_requirement + "]," + + "[clean_direction_requirement = " + clean_direction_requirement + "]," + + "[clean_intensity_requirement = " + clean_intensity_requirement + "]" + ); } private final static SweeperOperateCmdHandler mSweeperOperateCmdHandler = new SweeperOperateCmdHandler(); private static CmdRequestCallback mCurrentCmdRequestCallback; private static final int MSG_CMD_EXECUTE_COUNT_DOWN = 10001; + private static final int MSG_CMD_EXECUTE_MOCK_SUCCESS = 10002; + /** + * 执行命令时倒计时的Handler + */ static class SweeperOperateCmdHandler extends Handler { @Override @@ -256,17 +762,26 @@ public class SweeperOperatePanelView extends LinearLayout{ if (msg.what == MSG_CMD_EXECUTE_COUNT_DOWN) { int seconds = (int) msg.obj; if (seconds > 0) { - mCurrentCmdRequestCallback.onCountDownTick(seconds); + if (mCurrentCmdRequestCallback != null) { + mCurrentCmdRequestCallback.onCountDownTick(seconds); + } Message newMsg = Message.obtain(); newMsg.what = MSG_CMD_EXECUTE_COUNT_DOWN; - newMsg.obj = seconds-1; + newMsg.obj = seconds - 1; mSweeperOperateCmdHandler.sendMessageDelayed(newMsg, 1000L); } else { if (mCurrentCmdRequestCallback != null) { mCurrentCmdRequestCallback.onCmdTimeout(); mCurrentCmdRequestCallback = null; } + removeMessages(MSG_CMD_EXECUTE_COUNT_DOWN); } + } else if (msg.what == MSG_CMD_EXECUTE_MOCK_SUCCESS) { + if (mCurrentCmdRequestCallback != null) { + mCurrentCmdRequestCallback.onCmdSuccess(); + mCurrentCmdRequestCallback = null; + } + removeMessages(MSG_CMD_EXECUTE_COUNT_DOWN); } } } diff --git a/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/util/SweeperFutianCmdUtil.java b/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/util/SweeperFutianCmdUtil.java index 92b1eaecaf..4fe8d9ff9c 100644 --- a/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/util/SweeperFutianCmdUtil.java +++ b/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/util/SweeperFutianCmdUtil.java @@ -8,17 +8,17 @@ import chassis.SpecialVehicleTaskCmdOuterClass; public class SweeperFutianCmdUtil { private static final int CLEAN_WORK_OPEN = 1; //清扫作业-开启 private static final int CLEAN_WORK_CLOSE = 2;//清扫作业-关闭 - private static final int CLEAN_MODE_PURE_SWEEP = 1;//作业模式-纯扫 - private static final int CLEAN_MODE_WASH_SWEEP = 2;//作业模式-洗扫 - private static final int CLEAN_MODE_PURE_WASH = 3;//作业模式-纯洗 - private static final int CLEAN_MODE_PURE_DRAW = 4;//作业模式-纯吸 + public static final int CLEAN_MODE_PURE_SWEEP = 1;//作业模式-纯扫 + public static final int CLEAN_MODE_WASH_SWEEP = 2;//作业模式-洗扫 + public static final int CLEAN_MODE_PURE_WASH = 3;//作业模式-纯洗 + public static final int CLEAN_MODE_PURE_DRAW = 4;//作业模式-纯吸 private static final int CLEAN_MODE_CLOSE = 5;//作业模式-关闭 - private static final int CLEAN_DIRECTION_BOTH_SIDE = 1;//清扫方向-两侧 - private static final int CLEAN_DIRECTION_LEFT_SIDE = 2;//清扫方向-左侧 - private static final int CLEAN_DIRECTION_RIGHT_SIDE = 3;//清扫方向-右侧 + public static final int CLEAN_DIRECTION_BOTH_SIDE = 1;//清扫方向-两侧 + public static final int CLEAN_DIRECTION_LEFT_SIDE = 2;//清扫方向-左侧 + public static final int CLEAN_DIRECTION_RIGHT_SIDE = 3;//清扫方向-右侧 private static final int CLEAN_DIRECTION_CLOSE = 4;//清扫方向-关闭 - private static final int CLEAN_INTENSITY_STRAND = 1;//作业强度-标准 - private static final int CLEAN_INTENSITY_STRONG = 2;//作业强度-加强 + public static final int CLEAN_INTENSITY_STRAND = 1;//作业强度-标准 + public static final int CLEAN_INTENSITY_STRONG = 2;//作业强度-加强 public static SpecialVehicleTaskCmdOuterClass.RoboSweeperFuTianTaskCmd buildCleanWorkStartCmd() { return buildCleanWorkCmd(CLEAN_WORK_OPEN); @@ -40,29 +40,41 @@ public class SweeperFutianCmdUtil { return buildTaskCmd(builder.build()); } + public static SpecialVehicleTaskCmdOuterClass.RoboSweeperFuTianTaskCmd buildCleanModePureDrawCmd() { + SpecialVehicleTaskCmdOuterClass.RoboSweeperFuTianCleanCmd.Builder builder = SpecialVehicleTaskCmdOuterClass.RoboSweeperFuTianCleanCmd.newBuilder(); + builder.setCleanModeRequirement(CLEAN_MODE_PURE_DRAW); + //不用设置作业方向,自动设置作业强度为:标准 + builder.setCleanIntensityRequirement(CLEAN_INTENSITY_STRAND); + return buildTaskCmd(builder.build()); + } + public static SpecialVehicleTaskCmdOuterClass.RoboSweeperFuTianTaskCmd buildCleanModeCloseCmd() { - return buildCleanModeCmd(CLEAN_MODE_CLOSE); + SpecialVehicleTaskCmdOuterClass.RoboSweeperFuTianCleanCmd.Builder builder = SpecialVehicleTaskCmdOuterClass.RoboSweeperFuTianCleanCmd.newBuilder(); + builder.setCleanModeRequirement(CLEAN_MODE_CLOSE); + //关闭清扫方向,待下次在选择 + builder.setCleanDirectionRequirement(CLEAN_DIRECTION_CLOSE); + //自动设置作业强度为:标准 + builder.setCleanIntensityRequirement(CLEAN_INTENSITY_STRAND); + return buildTaskCmd(builder.build()); } public static SpecialVehicleTaskCmdOuterClass.RoboSweeperFuTianTaskCmd buildCleanDirectionCmd(int value) { SpecialVehicleTaskCmdOuterClass.RoboSweeperFuTianCleanCmd.Builder builder = SpecialVehicleTaskCmdOuterClass.RoboSweeperFuTianCleanCmd.newBuilder(); builder.setCleanDirectionRequirement(value); + builder.setCleanIntensityRequirement(CLEAN_INTENSITY_STRAND); + // 同时作业强度默认:标准 return buildTaskCmd(builder.build()); } public static SpecialVehicleTaskCmdOuterClass.RoboSweeperFuTianTaskCmd buildCleanDirectionCloseCmd() { - return buildCleanDirectionCmd(CLEAN_DIRECTION_CLOSE); + SpecialVehicleTaskCmdOuterClass.RoboSweeperFuTianCleanCmd.Builder builder = SpecialVehicleTaskCmdOuterClass.RoboSweeperFuTianCleanCmd.newBuilder(); + builder.setCleanDirectionRequirement(CLEAN_DIRECTION_CLOSE); + //重置作业强度为标准 + builder.setCleanIntensityRequirement(CLEAN_INTENSITY_STRAND); + return buildTaskCmd(builder.build()); } - public static SpecialVehicleTaskCmdOuterClass.RoboSweeperFuTianTaskCmd buildCleanIntensityStandardCmd() { - return buildCleanIntensityCmd(CLEAN_INTENSITY_STRAND); - } - - public static SpecialVehicleTaskCmdOuterClass.RoboSweeperFuTianTaskCmd buildCleanIntensityStrongCmd() { - return buildCleanIntensityCmd(CLEAN_INTENSITY_STRONG); - } - - private static SpecialVehicleTaskCmdOuterClass.RoboSweeperFuTianTaskCmd buildCleanIntensityCmd(int value) { + public static SpecialVehicleTaskCmdOuterClass.RoboSweeperFuTianTaskCmd buildCleanIntensityCmd(int value) { SpecialVehicleTaskCmdOuterClass.RoboSweeperFuTianCleanCmd.Builder builder = SpecialVehicleTaskCmdOuterClass.RoboSweeperFuTianCleanCmd.newBuilder(); builder.setCleanIntensityRequirement(value); return buildTaskCmd(builder.build()); diff --git a/OCH/mogo-och-sweeper/src/main/res/drawable/sweeper_operate_panel_btn1_bg_selector.xml b/OCH/mogo-och-sweeper/src/main/res/drawable/sweeper_operate_panel_btn1_bg_selector.xml index e73562aa4f..ba7719ba91 100644 --- a/OCH/mogo-och-sweeper/src/main/res/drawable/sweeper_operate_panel_btn1_bg_selector.xml +++ b/OCH/mogo-och-sweeper/src/main/res/drawable/sweeper_operate_panel_btn1_bg_selector.xml @@ -1,4 +1,4 @@ - - + + \ No newline at end of file diff --git a/OCH/mogo-och-sweeper/src/main/res/drawable/sweeper_operate_panel_btn2_bg_selector.xml b/OCH/mogo-och-sweeper/src/main/res/drawable/sweeper_operate_panel_btn2_bg_selector.xml index 7f990b092f..c51538216c 100755 --- a/OCH/mogo-och-sweeper/src/main/res/drawable/sweeper_operate_panel_btn2_bg_selector.xml +++ b/OCH/mogo-och-sweeper/src/main/res/drawable/sweeper_operate_panel_btn2_bg_selector.xml @@ -1,6 +1,6 @@ - - - + + + \ No newline at end of file diff --git a/OCH/mogo-och-sweeper/src/main/res/layout/sweeper_operate_panel_view.xml b/OCH/mogo-och-sweeper/src/main/res/layout/sweeper_operate_panel_view.xml index d8ef44ecf0..99d21b9d10 100644 --- a/OCH/mogo-och-sweeper/src/main/res/layout/sweeper_operate_panel_view.xml +++ b/OCH/mogo-och-sweeper/src/main/res/layout/sweeper_operate_panel_view.xml @@ -6,7 +6,7 @@ android:layout_height="wrap_content"> - + app:layout_constraintLeft_toRightOf="@id/hint_clean_work" + app:layout_constraintTop_toTopOf="@id/hint_clean_work" /> + app:constraint_referenced_ids="hint_clean_work, btn_clean_work_open_close" /> + app:layout_constraintTop_toBottomOf="@id/clean_work_barrier" /> - + android:enabled="false" + app:layout_constraintLeft_toRightOf="@id/hint_clean_mode" + app:layout_constraintTop_toTopOf="@id/hint_clean_mode" /> - + android:enabled="false" + app:layout_constraintLeft_toRightOf="@id/btn_clean_mode_pure_sweep" + app:layout_constraintTop_toTopOf="@id/hint_clean_mode" /> - + android:enabled="false" + app:layout_constraintLeft_toLeftOf="@id/btn_clean_mode_pure_sweep" + app:layout_constraintTop_toBottomOf="@id/btn_clean_mode_pure_sweep" /> - + android:enabled="false" + app:layout_constraintLeft_toRightOf="@id/btn_clean_mode_sweep_wash" + app:layout_constraintTop_toTopOf="@id/btn_clean_mode_sweep_wash" /> + app:constraint_referenced_ids="hint_clean_mode, btn_clean_mode_pure_sweep, btn_clean_mode_pure_wash, btn_clean_mode_sweep_wash, btn_clean_mode_pure_absorption" /> + app:layout_constraintTop_toBottomOf="@id/clean_mode_barrier" /> - - - @@ -201,7 +209,7 @@ app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toBottomOf="@id/clean_direction_barrier" /> - -