[清扫车]上装面板基本逻辑和人工驾驶地图添加

This commit is contained in:
bxb
2023-02-03 18:19:17 +08:00
parent acd1b3b584
commit d616e4bc6d
20 changed files with 529 additions and 439 deletions

View File

@@ -53,7 +53,6 @@ dependencies {
implementation rootProject.ext.dependencies.rxandroid
implementation rootProject.ext.dependencies.androidxcardview
implementation project(":OCH:mogo-och-common-module")
implementation rootProject.ext.dependencies.androidxrecyclerview
}

View File

@@ -0,0 +1,12 @@
package com.mogo.och.sweeper.callback;
import com.mogo.och.sweeper.constant.OperateStateEnum;
import chassis.ChassisStatesOuterClass;
/**
* 上装状态回调
*/
public interface CleaningModeStateCallback {
void cleaningModeState(OperateStateEnum cleaningModeState, ChassisStatesOuterClass.SweeperFuTianTaskSystemStates cleanSystemState,boolean isSelectPureSweepMode);
}

View File

@@ -0,0 +1,12 @@
package com.mogo.och.sweeper.constant
/**
* 上装面板操作状态
*/
enum class OperateStateEnum(val code: Int) {
SYNCING_STATUS( 1),//清扫车底盘状态同步中
STARTING_STATUS( 2),//上装中
FAIL_STATUS( 3),//上装失败
SUCCESS_STATUS(4),//上装成功
NO_STATUS(-1);//暂无模式
}

View File

@@ -25,7 +25,6 @@ import com.mogo.map.marker.IMogoMarkerManager;
import com.mogo.map.uicontroller.IMogoMapUIController;
import com.mogo.map.uicontroller.VisualAngleMode;
import com.mogo.och.sweeper.R;
import com.mogo.och.sweeper.ui.SweeperOperatePanelView;
import com.mogo.och.sweeper.view.SweeperCurrentTaskInfoView;
import com.mogo.och.sweeper.view.SweeperTrafficDataView;
import com.mogo.och.sweeper.view.SweeperWorkModeView;
@@ -37,7 +36,8 @@ import com.mogo.och.sweeper.view.SweeperWorkModeView;
*
* @author tongchenfei
*/
public abstract class BaseSweeperTabFragment<V extends IView, P extends Presenter<V>> extends MvpFragment<V, P> implements IMogoMapListener {
public abstract class BaseSweeperTabFragment<V extends IView, P extends Presenter<V>> extends MvpFragment<V, P> implements IMogoMapListener,
View.OnClickListener {
private static final String TAG = "BaseOchFragment";
//地图放大缩小
@@ -56,16 +56,16 @@ public abstract class BaseSweeperTabFragment<V extends IView, P extends Presente
private SweeperTrafficDataView mTrafficDataView;
//清扫车模式展示
private SweeperWorkModeView mClWorkMode;
//清扫车模式选择面板
private SweeperOperatePanelView mOperatePanel;
//当前任务面板
private SweeperCurrentTaskInfoView mCurrentTaskView;
//人工驾驶地图View组控制
private Group mGroupNaviPanel;
//人工驾驶地图Fragment
private SweeperAmapNaviFragment mOchAmapNaviFragment;
//关闭人工驾驶小地图
private ImageView mCloseNavIcon;
//人工驾驶地图View
private FrameLayout mFlNaviPanelContainer;
//
private ImageView mRefreshNavi;
public static final String TYPE_ENTRANCE = "entrance";
public boolean isAnimateRunning = false;
@@ -80,19 +80,19 @@ public abstract class BaseSweeperTabFragment<V extends IView, P extends Presente
@Override
protected void initViews() {
groupTestPanel = findViewById(R.id.groupTestPanel);
mGroupNaviPanel = findViewById(R.id.group_navi_panel);
flTaskListPanelContainer = findViewById(R.id.module_mogo_och_task_list_container);
mTrafficDataView = findViewById(R.id.sweeper_arc);
panelView = LayoutInflater.from(getContext()).inflate(getTaskListPanelViewId(), flTaskListPanelContainer);
mSwitchMapModeLayout = findViewById(R.id.sweeper_switch_model_layout);
mSwitchMapModeImage = findViewById(R.id.sweeper_switch_model_icon);
mClWorkMode = findViewById(R.id.sweeper_cl_work_mode);
mOperatePanel = findViewById(R.id.module_mogo_och_sweeper_operate_panel);
mCurrentTaskView = findViewById(R.id.sweeper_current_task_view);
mSettingBtn = findViewById(R.id.module_mogo_och_setting_layout);
mBadcaseBtn = findViewById(R.id.module_mogo_och_badcase_rl);
mAICollectBtn = findViewById(R.id.module_mogo_och_ai_collet_rl);
mCloseNavIcon = findViewById(R.id.sweeper_close_navi_icon);
mFlNaviPanelContainer = findViewById(R.id.module_mogo_och_navi_panel_container);
mRefreshNavi = findViewById(R.id.sweeper_refresh_navi);
initListener();
hideEagleConfig();
//设置左下角四个按钮监听事件
@@ -111,7 +111,6 @@ public abstract class BaseSweeperTabFragment<V extends IView, P extends Presente
findViewById(R.id.btnAutopilotRunning).setOnClickListener(view ->
debugAutoPilotStatus(IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING)
);
showAmapNaviToStationFragment(true);
}
private void updateSwitchMapIcon() {
@@ -136,6 +135,8 @@ public abstract class BaseSweeperTabFragment<V extends IView, P extends Presente
private void initListener() {
MogoMapListenerHandler.Companion.getMogoMapListenerHandler().registerHostMapListener(TAG, this);
mCloseNavIcon.setOnClickListener(this);
mRefreshNavi.setOnClickListener(this);
}
/**
@@ -150,6 +151,7 @@ public abstract class BaseSweeperTabFragment<V extends IView, P extends Presente
panelView.setVisibility(View.GONE);
}
}
/**
* 当前任务面板隐藏或显示
*
@@ -162,6 +164,7 @@ public abstract class BaseSweeperTabFragment<V extends IView, P extends Presente
mCurrentTaskView.setVisibility(View.GONE);
}
}
/**
* 清扫模式展示面板
*
@@ -179,6 +182,7 @@ public abstract class BaseSweeperTabFragment<V extends IView, P extends Presente
public SweeperCurrentTaskInfoView getCurrentTaskPanelView() {
return mCurrentTaskView;
}
/**
* 清扫车任务列表面板view在{@link #initViews()}时候添加到container中
*
@@ -210,6 +214,15 @@ public abstract class BaseSweeperTabFragment<V extends IView, P extends Presente
}
}
/**
* 车辆基本信息View
*
* @return
*/
public SweeperTrafficDataView getTrafficDataView() {
return mTrafficDataView;
}
@Override
public void onDestroy() {
super.onDestroy();
@@ -307,17 +320,25 @@ public abstract class BaseSweeperTabFragment<V extends IView, P extends Presente
protected void showAmapNaviToStationFragment(boolean isShow) {
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
if (isShow) {
mGroupNaviPanel.setVisibility(View.VISIBLE);
mOchAmapNaviFragment = SweeperAmapNaviFragment.newInstance();
if (mOchAmapNaviFragment.isAdded()) {
return;
}
transaction.add(R.id.module_mogo_och_navi_panel_container, mOchAmapNaviFragment).show(mOchAmapNaviFragment);
transaction.commitAllowingStateLoss();
mCloseNavIcon.setVisibility(View.VISIBLE);
mFlNaviPanelContainer.setVisibility(View.VISIBLE);
} else {
mCloseNavIcon.setVisibility(View.GONE);
mFlNaviPanelContainer.setVisibility(View.GONE);
mGroupNaviPanel.setVisibility(View.GONE);
}
}
@Override
public void onClick(View v) {
int id = v.getId();
if (id == R.id.sweeper_close_navi_icon) {
mGroupNaviPanel.setVisibility(View.GONE);
} else if (id == R.id.sweeper_refresh_navi) {
}
}
}

View File

@@ -2,26 +2,32 @@ package com.mogo.och.sweeper.fragment
import android.view.View
import androidx.recyclerview.widget.LinearLayoutManager
import chassis.ChassisStatesOuterClass
import com.amap.api.navi.model.NaviLatLng
import com.mogo.och.common.module.map.AmapNaviToDestinationModel
import com.mogo.och.sweeper.R
import com.mogo.och.sweeper.bean.TaskInfoBean
import com.mogo.och.sweeper.callback.CleaningModeStateCallback
import com.mogo.och.sweeper.constant.OperateStateEnum
import com.mogo.och.sweeper.constant.TaskMenuTypeEnum
import com.mogo.och.sweeper.presenter.SweeperPresenter
import com.mogo.och.sweeper.ui.adapter.TaskListAdapter
import com.mogo.och.sweeper.ui.popwindow.MenuPopWindow
import com.mogo.och.sweeper.util.SweeperFutianCmdUtil
import kotlinx.android.synthetic.main.fragment_och_sweeper.*
/**
* 清扫车主界面
*/
class SweeperFragment : BaseSweeperTabFragment<SweeperFragment?, SweeperPresenter?>(), MenuPopWindow.OnMenuItemOnClickListener {
class SweeperFragment : BaseSweeperTabFragment<SweeperFragment?, SweeperPresenter?>(), MenuPopWindow.OnMenuItemOnClickListener{
private var mAdapter: TaskListAdapter? = null
//当前任务操作菜单
private var mTaskMenuPopWindow: MenuPopWindow? = null
//
private var mPosition: Int = -1
private val mutableList: MutableList<TaskInfoBean> by lazy { mutableListOf() }
private var subTaskType:Int=1;//1:自动驾驶子任务 2人工驾驶子任务
//当前经纬度
private var mCurLatitude = 0.0
private var mCurLongitude = 0.0
override fun getTagName(): String {
return "SweepersFragment"
}
@@ -44,8 +50,9 @@ class SweeperFragment : BaseSweeperTabFragment<SweeperFragment?, SweeperPresente
rvTaskList?.layoutManager = linearLayoutManager
rvTaskList?.adapter = mAdapter
mAdapter?.setOnTaskItemClickListener(onTaskItemClickListener)
mTaskMenuPopWindow = context?.let { MenuPopWindow(it, this) }
initListener()
showAmapNaviToStationFragment(true)
startNaviToStation(true, 40.199247410363796, 116.73367125257714, 40.20070929640184, 116.73582650844378)
}
override fun createPresenter(): SweeperPresenter {
@@ -93,23 +100,9 @@ class SweeperFragment : BaseSweeperTabFragment<SweeperFragment?, SweeperPresente
setShowTaskListPanelView(false)
workModePanelView.visibility = View.VISIBLE
setShowCurrentTaskPanelView(true)
currentTaskPanelView.setData(mutableList, mPosition)
}
//清扫模式选择面板打开关闭处理
workModePanelView.setOnClickListener { v: View? ->
}
//任务操作菜单打开关闭处理
currentTaskPanelView.getIvMore().setOnClickListener { v: View? ->
if (mTaskMenuPopWindow?.isShowing != true) {
mTaskMenuPopWindow?.showAsDropDown(
workModePanelView,
resources.getDimension(R.dimen.dp_580).toInt(),
resources.getDimension(R.dimen.dp_36).toInt()
)
} else {
mTaskMenuPopWindow?.dismiss()
}
currentTaskPanelView.setData(workModePanelView,mutableList, mPosition,this)
//mock数据
workModePanelView.setSweeperFutianCleanSystemState(subTaskType,SweeperFutianCmdUtil.buildSweeperFuTionCleanSystemStateMockData(),trafficDataView)
}
}
@@ -136,4 +129,18 @@ class SweeperFragment : BaseSweeperTabFragment<SweeperFragment?, SweeperPresente
}
}
}
fun onSweeperFutianCleanSystemState(cleanSystemState: ChassisStatesOuterClass.SweeperFuTianTaskSystemStates) {
workModePanelView.setSweeperFutianCleanSystemState(subTaskType,cleanSystemState,trafficDataView)
}
/**
* 导航去目的地
*/
private fun startNaviToStation(isVoicePlay: Boolean, startLat: Double, startLng: Double, endLat: Double, endLng: Double) {
AmapNaviToDestinationModel.getInstance(context).destroyAmaNavi()
val startNaviLatLng = NaviLatLng(startLat, startLng)
val endNaviLatLng = NaviLatLng(endLat, endLng)
AmapNaviToDestinationModel.getInstance(context).initAMapNavi(startNaviLatLng, endNaviLatLng)
AmapNaviToDestinationModel.getInstance(context).setVoiceIsMute(isVoicePlay)
}
}

View File

@@ -6,13 +6,16 @@ import com.mogo.commons.AbsMogoApplication;
import com.mogo.commons.mvp.Presenter;
import com.mogo.eagle.core.data.autopilot.AutopilotStatusInfo;
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener;
import com.mogo.eagle.core.function.api.autopilot.IMoGoSweeperFutianCleanSystemListener;
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager;
import com.mogo.eagle.core.function.call.autopilot.CallerSweeperFutianCleanSystemListenerManager;
import com.mogo.eagle.core.utilcode.util.UiThreadHandler;
import com.mogo.och.common.module.manager.OCHAdasAbilityManager;
import com.mogo.och.sweeper.callback.ISweeperADASStatusCallback;
import com.mogo.och.sweeper.callback.ISweeperControllerStatusCallback;
import com.mogo.och.sweeper.fragment.SweeperFragment;
import com.mogo.och.sweeper.model.SweeperTaskModel;
import com.mogo.och.sweeper.util.SweeperFutianCmdUtil;
import com.mogo.och.sweeper.util.SweeperTrajectoryManager;
import org.jetbrains.annotations.NotNull;
@@ -20,8 +23,10 @@ import org.jetbrains.annotations.NotNull;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.LifecycleOwner;
import chassis.ChassisStatesOuterClass;
import mogo.telematics.pad.MessagePad;
import mogo_msg.MogoReportMsg;
import planning.RoboSweeperTaskIndexOuterClass;
import system_master.SystemStatusInfo;
/**
@@ -30,7 +35,7 @@ import system_master.SystemStatusInfo;
* @author tongchenfei
*/
public class SweeperPresenter extends Presenter<SweeperFragment>
implements IMoGoAutopilotStatusListener, ISweeperControllerStatusCallback, ISweeperADASStatusCallback{
implements IMoGoAutopilotStatusListener, ISweeperControllerStatusCallback, ISweeperADASStatusCallback, IMoGoSweeperFutianCleanSystemListener {
private static final String TAG = "BusPresenter";
@@ -41,6 +46,8 @@ public class SweeperPresenter extends Presenter<SweeperFragment>
super(view);
//2021.11.1 鹰眼架构整合由IMoGoAutopilotStatusListener逐步替代IMogoAdasOCHCallback接口
CallerAutoPilotStatusListenerManager.INSTANCE.addListener(TAG, this);
//清扫车模式和贴边数据回调监听
CallerSweeperFutianCleanSystemListenerManager.INSTANCE.addListener(TAG,this);
SweeperTaskModel.getInstance().init();
OCHAdasAbilityManager.getInstance().init(AbsMogoApplication.getApp());
}
@@ -66,6 +73,7 @@ public class SweeperPresenter extends Presenter<SweeperFragment>
public void releaseListener() {
SweeperTaskModel.getInstance().setControllerStatusCallback(null);
SweeperTaskModel.getInstance().setAdasStatusCallback(null);
CallerSweeperFutianCleanSystemListenerManager.INSTANCE.removeListener(TAG);
}
public void restartAutopilot() {
@@ -175,4 +183,13 @@ public class SweeperPresenter extends Presenter<SweeperFragment>
public void onStartAdasFailure() {
}
@Override
public void onSweeperFutianCleanSystemState(@NonNull ChassisStatesOuterClass.SweeperFuTianTaskSystemStates cleanSystemState) {
runOnUIThread(() ->mView.onSweeperFutianCleanSystemState(cleanSystemState));
}
@Override
public void onSweeperFutianTaskIndexData(@NonNull RoboSweeperTaskIndexOuterClass.RoboSweeperTaskIndex roboSweeperTaskIndex) {
}
}

View File

@@ -1,5 +1,34 @@
package com.mogo.och.sweeper.ui;
import android.content.Context;
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 com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotManager;
import com.mogo.eagle.core.utilcode.mogo.view.OnPreventFastClickListener;
import com.mogo.eagle.core.utilcode.util.ThreadUtils;
import com.mogo.eagle.core.utilcode.util.ToastUtils;
import com.mogo.och.sweeper.R;
import com.mogo.och.sweeper.callback.CleaningModeStateCallback;
import com.mogo.och.sweeper.constant.OperateStateEnum;
import com.mogo.och.sweeper.util.SweeperFutianCmdUtil;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import chassis.ChassisStatesOuterClass;
import chassis.SpecialVehicleTaskCmdOuterClass;
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;
@@ -10,39 +39,6 @@ import static com.mogo.och.sweeper.util.SweeperFutianCmdUtil.CLEAN_MODE_PURE_SWE
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.IMoGoSweeperFutianCleanSystemListener;
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotManager;
import com.mogo.eagle.core.function.call.autopilot.CallerSweeperFutianCleanSystemListenerManager;
import com.mogo.eagle.core.utilcode.mogo.view.OnPreventFastClickListener;
import com.mogo.eagle.core.utilcode.util.ThreadUtils;
import com.mogo.eagle.core.utilcode.util.ToastUtils;
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.ChassisStatesOuterClass;
import chassis.SpecialVehicleTaskCmdOuterClass;
import planning.RoboSweeperTaskIndexOuterClass;
/**
* 清扫车操作面板View
*/
@@ -52,7 +48,6 @@ public class SweeperOperatePanelView extends LinearLayout {
private static final int CMD_EXECUTE_TIMEOUT_SECONDS = 30;
private static final int CMD_EXECUTE_MOCK_SUCCESS_SECONDS = 3;
CheckedTextView mBtnCleanWorkOpenClose;//开关
CheckedTextView mBtnCleanModePureSweep;//纯扫
CheckedTextView mBtnCleanModePureWash;//纯洗
CheckedTextView mBtnCleanModeSweepWash;//洗扫
@@ -65,7 +60,6 @@ public class SweeperOperatePanelView extends LinearLayout {
LinearLayout mLoadingContainer;//loading container
TextView mLoadingHintTop;//loading 提示-上面
TextView mLoadingHintBottom;//loading 提示-下面
private TextView mBtnCancel;//取消
private TextView mBtnReset;//复位
// 作业模式相关操作按钮的id
@@ -112,6 +106,12 @@ public class SweeperOperatePanelView extends LinearLayout {
put(R.id.btn_clean_intensity_strong, CLEAN_INTENSITY_STRONG);
}
};
private boolean isSelectPureSweepMode = false;//用于标注是否选中纯扫
private CleaningModeStateCallback cleaningModeStateCallback;
//设置清扫模式数据
private static ChassisStatesOuterClass.SweeperFuTianTaskSystemStates.Builder builder =
ChassisStatesOuterClass.SweeperFuTianTaskSystemStates.newBuilder();
public SweeperOperatePanelView(Context context) {
super(context);
@@ -134,7 +134,6 @@ public class SweeperOperatePanelView extends LinearLayout {
private void initView(Context context) {
LayoutInflater.from(context).inflate(R.layout.sweeper_operate_panel_view, this, true);
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);
@@ -147,13 +146,11 @@ public class SweeperOperatePanelView extends LinearLayout {
mLoadingContainer = findViewById(R.id.loading_hint_container);
mLoadingHintTop = findViewById(R.id.loading_hint_top);
mLoadingHintBottom = findViewById(R.id.loading_hint_bottom);
mBtnCancel = findViewById(R.id.btn_operate_panel_cancel);
mBtnReset = findViewById(R.id.btn_operate_panel_reset);
initViewListener();
}
private void initViewListener() {
setClickListener(mBtnCleanWorkOpenClose, (v) -> onCleanWorkBtnClick());
setClickListener(mBtnCleanModePureSweep, (v) -> onCleanModeBtnClick(v));
setClickListener(mBtnCleanModePureWash, (v) -> onCleanModeBtnClick(v));
setClickListener(mBtnCleanModeSweepWash, (v) -> onCleanModeBtnClick(v));
@@ -164,94 +161,6 @@ public class SweeperOperatePanelView extends LinearLayout {
setClickListener(mBtnCleanIntensityStandard, (v) -> onCleanIntensityBtnClick(v));
setClickListener(mBtnCleanIntensityStrong, (v) -> onCleanIntensityBtnClick(v));
setClickListener(mBtnReset, (v) -> onOperateReset());
setClickListener(mBtnCancel, (v) -> onOperateCancel());
}
/**
* 清扫任务开关按钮点击事件
*/
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(ChassisStatesOuterClass.SweeperFuTianTaskSystemStates cleanSystemState) {
boolean success = false;
if (cleanSystemState == null) {
return success;
}
if (isCloseAction) {
success = !cleanSystemState.getSecuMotWorkSts();
} else {
success = cleanSystemState.getSecuMotWorkSts();
}
return success;
}
@Override
public void onCmdSuccess() {
runOnUIThread(() -> {
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() {
//按钮样式恢复原样
runOnUIThread(() -> {
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);
}
}
/**
@@ -272,12 +181,15 @@ public class SweeperOperatePanelView extends LinearLayout {
&& currentChoosedModeBtnView.getId() == currentClickView.getId();
//是否纯吸View
boolean isPureAbsorptionClick = currentClickView.getId() == R.id.btn_clean_mode_pure_absorption;
builder.setSecuWorkTonSts(isPureAbsorptionClick&&isClickCurrentChoosedModeBtn);
//是否纯洗View
boolean isPureWashClick = currentClickView.getId() == R.id.btn_clean_mode_pure_wash;
builder.setSecuModWashSts(isPureWashClick&&isClickCurrentChoosedModeBtn);
//是否纯扫View
boolean isPureSweepClick = currentClickView.getId() == R.id.btn_clean_mode_pure_sweep;
//是否洗扫View
boolean isWashSweepClick = currentClickView.getId() == R.id.btn_clean_mode_sweep_wash;
builder.setSecuModWashSweepSts(isWashSweepClick&&isClickCurrentChoosedModeBtn);
CmdRequestCallback cmdRequestCallback = new CmdRequestCallback() {
@Override
@@ -303,7 +215,7 @@ public class SweeperOperatePanelView extends LinearLayout {
// 纯吸
boolean clean_mode_pure_draw = cleanSystemState.getSecuWorkTonSts();
// 纯扫 模式判断不是另外其他3个模式同时有清扫方向说明开启了纯扫模式
boolean clean_mode_pure_sweep = checkIfCleanModePureSweep(cleanSystemState);
boolean clean_mode_pure_sweep = SweeperFutianCmdUtil.checkIfCleanModePureSweep(cleanSystemState);
// 关闭作业模式实际执行了3个操作 关闭作业模式 关闭清扫方向 切换标准强度,实际以关闭作业模式成功为准)
boolean clean_mode_close = !clean_mode_wash_sweep
&& !clean_mode_pure_wash
@@ -312,16 +224,20 @@ public class SweeperOperatePanelView extends LinearLayout {
if (isClickCurrentChoosedModeBtn && clean_mode_close) {// 关闭放第一判断
success = clean_mode_close;
isSelectPureSweepMode = false;
} else if (isPureSweepClick) {
//success = clean_mode_pure_sweep;
//纯扫 这个模式实际在福田清扫车上没有这个按钮,只是发送指令给特种车端,默认此命令肯定是正确的
success = true;
} else if (isPureWashClick) {
success = clean_mode_pure_wash;
isSelectPureSweepMode = false;
} else if (isWashSweepClick) {
success = clean_mode_wash_sweep;
isSelectPureSweepMode = false;
} else if (isPureAbsorptionClick) {
success = clean_mode_pure_draw;
isSelectPureSweepMode = false;
}
return success;
}
@@ -395,6 +311,9 @@ public class SweeperOperatePanelView extends LinearLayout {
boolean isLeftSide = currentClickView.getId() == R.id.btn_clean_direction_left_side;
boolean isRightSide = currentClickView.getId() == R.id.btn_clean_direction_right_side;
boolean isBothSide = currentClickView.getId() == R.id.btn_clean_direction_both_side;
builder.setSecuWorkLeftSts(isLeftSide&&isClickCurrentChoosedDirectionBtn);
builder.setSecuWorkRightSts(isRightSide&&isClickCurrentChoosedDirectionBtn);
builder.setSecuWorkOnBothsidesSts(isBothSide&&isClickCurrentChoosedDirectionBtn);
CmdRequestCallback cmdRequestCallback = new CmdRequestCallback() {
@@ -484,7 +403,9 @@ public class SweeperOperatePanelView extends LinearLayout {
private void onCleanIntensityBtnClick(final View currentClickView) {
boolean isStandardBtnClick = currentClickView.getId() == R.id.btn_clean_intensity_standard;
builder.setSecuWorkStandSts(isStandardBtnClick);
boolean isStrongBtnClick = currentClickView.getId() == R.id.btn_clean_intensity_strong;
builder.setSecuWorkStrongSts(isStrongBtnClick);
CmdRequestCallback cmdRequestCallback = new CmdRequestCallback() {
@Override
public void onSendCmd() {
@@ -662,6 +583,9 @@ public class SweeperOperatePanelView extends LinearLayout {
timeout
));
mLoadingHintBottom.setVisibility(timeout < 0 ? View.INVISIBLE : View.VISIBLE);
if (cleaningModeStateCallback != null && timeout > 0) {
cleaningModeStateCallback.cleaningModeState(OperateStateEnum.STARTING_STATUS, builder.build(), isSelectPureSweepMode);
}
});
}
@@ -694,6 +618,9 @@ public class SweeperOperatePanelView extends LinearLayout {
* 命令执行成功toast
*/
private void showCmdExecuteSuccessToast() {
if (cleaningModeStateCallback != null) {
cleaningModeStateCallback.cleaningModeState(OperateStateEnum.SUCCESS_STATUS, builder.build(), isSelectPureSweepMode);
}
ToastUtils.showLong("设备已响应,操作成功");
}
@@ -701,42 +628,12 @@ public class SweeperOperatePanelView extends LinearLayout {
* 命令执行超时toast
*/
private void showCmdExecuteTimeoutToast() {
if (cleaningModeStateCallback != null) {
cleaningModeStateCallback.cleaningModeState(OperateStateEnum.FAIL_STATUS, builder.build(), isSelectPureSweepMode);
}
ToastUtils.showLong("超时未响应,操作失败");
}
/**
* 根据底盘数据恢复操作面板中相关按钮状态 成功toast
*/
private void showRecoverPanelButtonStateSuccessToast() {
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
@@ -755,62 +652,29 @@ public class SweeperOperatePanelView extends LinearLayout {
});
}
// 当前时间戳
private long mCurrentTimeMillis;
// 底盘数据回调时间间隔
private static final long VEHICLE_STATE_INTERVAL_MILLIS = 500L;
/**
* 底盘数据透传listener
*/
private final IMoGoSweeperFutianCleanSystemListener mIMoGoAutopilotVehicleStateListener = new IMoGoSweeperFutianCleanSystemListener() {
@Override
public void onSweeperFutianCleanSystemState(@NonNull ChassisStatesOuterClass.SweeperFuTianTaskSystemStates cleanSystemState) {
long current = System.currentTimeMillis();
if (current - mCurrentTimeMillis <= VEHICLE_STATE_INTERVAL_MILLIS) {
return;
}
mCurrentTimeMillis = current;
Log.d(TAG, "onSweeperFutianCleanSystemState");
// 第一次进入时同步底盘状态,只拿第一次的数据
if (mSyncingVehicleState) {
onSyncVehicleStateCallBack(cleanSystemState);
return;
}
// 有命令正在执行
if (mCurrentCmdRequestCallback != null) {
Log.d(TAG, "getSecuWorkLeftSts = " + cleanSystemState.getSecuWorkLeftSts());
if (mCurrentCmdRequestCallback.onCheckIfCmdSuccess(cleanSystemState)) {
mCurrentCmdRequestCallback.onCmdSuccess();
mCurrentCmdRequestCallback = null;
}
}
}
@Override
public void onSweeperFutianTaskIndexData(@NonNull RoboSweeperTaskIndexOuterClass.RoboSweeperTaskIndex roboSweeperTaskIndex) {
}
};
public void setSweeperFutianCleanSystemState(@NonNull ChassisStatesOuterClass.SweeperFuTianTaskSystemStates cleanSystemState,
CleaningModeStateCallback cleaningModeStateCallback) {
this.cleaningModeStateCallback = cleaningModeStateCallback;
onSyncVehicleStateCallBack(cleanSystemState);
// 有命令正在执行
// if (mCurrentCmdRequestCallback != null) {
// Log.d(TAG, "getSecuWorkLeftSts = " + cleanSystemState.getSecuWorkLeftSts());
// if (mCurrentCmdRequestCallback.onCheckIfCmdSuccess(cleanSystemState)) {
// mCurrentCmdRequestCallback.onCmdSuccess();
// mCurrentCmdRequestCallback = null;
// }
// }
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
CallerSweeperFutianCleanSystemListenerManager.INSTANCE.addListener(TAG, mIMoGoAutopilotVehicleStateListener);
// 最终调试时需要打开
syncVehicleStateAndRecoverOperatePanelStates();
//syncVehicleStateAndRecoverOperatePanelStates();
// Mock VehicleState 数据回调
// UiThreadHandler.postDelayed(() -> {
// onSyncVehicleStateCallBack(SweeperFutianCmdUtil.buildSweeperFuTionCleanSystemStateMockData());
// }, 3000L);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
CallerSweeperFutianCleanSystemListenerManager.INSTANCE.removeListener(TAG);
// UiThreadHandler.postDelayed(() -> {
// onSyncVehicleStateCallBack(SweeperFutianCmdUtil.buildSweeperFuTionCleanSystemStateMockData());
// }, 3000L);
}
/**
@@ -819,12 +683,10 @@ public class SweeperOperatePanelView extends LinearLayout {
private synchronized void syncVehicleStateAndRecoverOperatePanelStates() {
// show sync loading
showLoadingMask("状态同步中,请稍后", -1);
mSyncingVehicleState = true;
}
private synchronized void onSyncVehicleStateCallBack(ChassisStatesOuterClass.SweeperFuTianTaskSystemStates cleanSystemState) {
if (cleanSystemState == null) return;
mSyncingVehicleState = false;
// 清扫作业开启状态以电机状态为true代表Open成功实际控制端控制步骤为1.发送远程控制上装指令 2.发送电机启动指令)
boolean clean_open_requirement = cleanSystemState.getSecuMotWorkSts();
// 作业模式状态
@@ -844,22 +706,13 @@ public class SweeperOperatePanelView extends LinearLayout {
boolean clean_direction_both_side = cleanSystemState.getSecuWorkOnBothsidesSts();
// 纯扫 模式判断不是另外其他3个模式同时有清扫方向说明开启了纯扫模式
boolean clean_mode_pure_sweep = checkIfCleanModePureSweep(cleanSystemState);
boolean clean_mode_pure_sweep = SweeperFutianCmdUtil.checkIfCleanModePureSweep(cleanSystemState);
// 作业强度状态
boolean clean_intensity_standard = cleanSystemState.getSecuWorkStandSts();
boolean clean_intensity_strong = cleanSystemState.getSecuWorkStrongSts();
runOnUIThread(() -> {
if (clean_open_requirement) {
// 打开状态
mBtnCleanWorkOpenClose.setText("Close");
mBtnCleanWorkOpenClose.setChecked(true);
} else {
// 关闭状态
mBtnCleanWorkOpenClose.setText("Open");
mBtnCleanWorkOpenClose.setChecked(false);
}
if (clean_mode_pure_sweep) {
//纯扫
mBtnCleanModePureSweep.setChecked(true);
@@ -904,39 +757,9 @@ public class SweeperOperatePanelView extends LinearLayout {
setCleanIntensityStrong();
}
hideLoadingMask();
showRecoverPanelButtonStateSuccessToast();
});
}
/**
* 通过底盘数据判断是纯扫模式
*
* @param cleanSystemState
* @return
*/
private boolean checkIfCleanModePureSweep(ChassisStatesOuterClass.SweeperFuTianTaskSystemStates cleanSystemState) {
// 作业模式状态
// 洗扫
boolean clean_mode_wash_sweep = cleanSystemState.getSecuModWashSweepSts();
// 纯洗
boolean clean_mode_pure_wash = cleanSystemState.getSecuModWashSts();
// 纯吸
boolean clean_mode_pure_draw = cleanSystemState.getSecuWorkTonSts();
// 清扫方向状态
// 左侧
boolean clean_direction_left_side = cleanSystemState.getSecuWorkLeftSts();
// 右侧
boolean clean_direction_right_side = cleanSystemState.getSecuWorkRightSts();
// 两侧
boolean clean_direction_both_side = cleanSystemState.getSecuWorkOnBothsidesSts();
// 纯扫 模式判断不是另外其他3个模式同时有清扫方向说明开启了纯扫模式
boolean clean_mode_pure_sweep = (clean_direction_left_side || clean_direction_right_side || clean_direction_both_side)
&& (!clean_mode_wash_sweep && !clean_mode_pure_wash && !clean_mode_pure_draw);
return clean_mode_pure_sweep;
}
/**
* 发送清扫车相关作业命令
*
@@ -962,7 +785,7 @@ public class SweeperOperatePanelView extends LinearLayout {
msg.obj = timeout;
mSweeperOperateCmdHandler.sendMessage(msg);
// Mock Cmd Success
// mockSendCmdSuccess();
mockSendCmdSuccess();
}
private void mockSendCmdSuccess() {
@@ -985,21 +808,15 @@ public class SweeperOperatePanelView extends LinearLayout {
);
}
/**
* 取消关闭面板
*/
private void onOperateCancel(){
this.setVisibility(View.GONE);
}
/**
* 复位
*/
private void onOperateReset(){
private void onOperateReset() {
}
private final static SweeperOperateCmdHandler mSweeperOperateCmdHandler = new SweeperOperateCmdHandler();
private static CmdRequestCallback mCurrentCmdRequestCallback;//发送命令后的回调
private boolean mSyncingVehicleState;//第一次进入页面时,同步底盘状态的标志位
private static final int MSG_CMD_EXECUTE_COUNT_DOWN = 10001;
private static final int MSG_CMD_EXECUTE_MOCK_SUCCESS = 10002;
@@ -1030,8 +847,10 @@ public class SweeperOperatePanelView extends LinearLayout {
}
} else if (msg.what == MSG_CMD_EXECUTE_MOCK_SUCCESS) {
if (mCurrentCmdRequestCallback != null) {
mCurrentCmdRequestCallback.onCmdSuccess();
mCurrentCmdRequestCallback = null;
if (mCurrentCmdRequestCallback.onCheckIfCmdSuccess(builder.build())) {
mCurrentCmdRequestCallback.onCmdSuccess();
mCurrentCmdRequestCallback = null;
}
}
removeMessages(MSG_CMD_EXECUTE_COUNT_DOWN);
}

View File

@@ -8,13 +8,16 @@ import android.view.View
import android.view.ViewGroup.LayoutParams
import android.widget.PopupWindow
import android.widget.TextView
import chassis.ChassisStatesOuterClass
import com.mogo.och.sweeper.R
import com.mogo.och.sweeper.callback.CleaningModeStateCallback
import com.mogo.och.sweeper.constant.OperateStateEnum
import com.mogo.och.sweeper.constant.TaskMenuTypeEnum
/**
* 当前任务操作菜单栏
*/
class MenuPopWindow : PopupWindow, View.OnClickListener {
class MenuPopWindow : PopupWindow, View.OnClickListener{
private var mTvJumpOverTask: TextView? = null

View File

@@ -0,0 +1,50 @@
package com.mogo.och.sweeper.ui.popwindow
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.PopupWindow
import android.widget.TextView
import chassis.ChassisStatesOuterClass
import com.mogo.och.sweeper.R
import com.mogo.och.sweeper.callback.CleaningModeStateCallback
import com.mogo.och.sweeper.ui.SweeperOperatePanelView
/**
* 清扫车面板浮窗
*/
class SweeperOperatePanelPopWindow : PopupWindow {
private var mOperatePanelView: SweeperOperatePanelView? = null
private var mBtnCancel: TextView? = null //取消
constructor(context: Context) : super(context) {
init(context)
}
private fun init(context: Context) {
setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
mOperatePanelView = LayoutInflater.from(context).inflate(R.layout.sweeper_popwindow_operate_panel, null) as SweeperOperatePanelView?
mBtnCancel = mOperatePanelView?.findViewById(R.id.btn_operate_panel_cancel)
width = ViewGroup.LayoutParams.WRAP_CONTENT
height = ViewGroup.LayoutParams.WRAP_CONTENT
contentView = mOperatePanelView
isFocusable = true
isOutsideTouchable = true
mBtnCancel?.setOnClickListener {
dismiss()
}
}
/**
* 设置清扫模式数据
*/
fun setCleanSystemState(
cleanSystemState: ChassisStatesOuterClass.SweeperFuTianTaskSystemStates,
cleaningModeStateCallback: CleaningModeStateCallback
) {
mOperatePanelView?.setSweeperFutianCleanSystemState(cleanSystemState, cleaningModeStateCallback)
}
}

View File

@@ -1,7 +1,7 @@
package com.mogo.och.sweeper.util;
import chassis.ChassisStatesOuterClass;
import chassis.SpecialVehicleTaskCmdOuterClass;
import chassis.VehicleStateOuterClass;
/**
* 清扫车-福田,构建业务命令数据的工具类
@@ -131,13 +131,67 @@ public class SweeperFutianCmdUtil {
.setRoboSweeperFutianCleanCmd(fuTianCleanCmd).build();
}
/**
* 判断是否有作业模式
* @param cleanSystemState
* @return true:没有作业模式 false有作业模式
*/
public static boolean checkIfCleanMode(ChassisStatesOuterClass.SweeperFuTianTaskSystemStates cleanSystemState){
return (!cleanSystemState.getSecuModWashSweepSts()&&!cleanSystemState.getSecuModWashSts()&&!cleanSystemState.getSecuWorkTonSts())&&
(!cleanSystemState.getSecuWorkLeftSts()&&!cleanSystemState.getSecuWorkRightSts()&&!cleanSystemState.getSecuWorkOnBothsidesSts());
}
/**
* 判断是否有清扫方向
* @param cleanSystemState
* @return true:没有清扫方向 false有清扫方向
*/
public static boolean checkIfCleanDirection(ChassisStatesOuterClass.SweeperFuTianTaskSystemStates cleanSystemState){
return !cleanSystemState.getSecuWorkLeftSts()&&!cleanSystemState.getSecuWorkRightSts()&&!cleanSystemState.getSecuWorkOnBothsidesSts();
}
/**
* 判断是否有作业强度
* @param cleanSystemState
* @return true:没有作业强度 false有作业强度
*/
public static boolean checkIfCleanIntensity(ChassisStatesOuterClass.SweeperFuTianTaskSystemStates cleanSystemState){
return !cleanSystemState.getSecuWorkLeftSts()&&!cleanSystemState.getSecuWorkRightSts()&&!cleanSystemState.getSecuWorkOnBothsidesSts();
}
/**
* 判断是否纯扫模式
*
* @param cleanSystemState
* @return
*/
public static boolean checkIfCleanModePureSweep(ChassisStatesOuterClass.SweeperFuTianTaskSystemStates cleanSystemState) {
// 作业模式状态
// 洗扫
boolean clean_mode_wash_sweep = cleanSystemState.getSecuModWashSweepSts();
// 纯洗
boolean clean_mode_pure_wash = cleanSystemState.getSecuModWashSts();
// 纯吸
boolean clean_mode_pure_draw = cleanSystemState.getSecuWorkTonSts();
// 清扫方向状态
// 左侧
boolean clean_direction_left_side = cleanSystemState.getSecuWorkLeftSts();
// 右侧
boolean clean_direction_right_side = cleanSystemState.getSecuWorkRightSts();
// 两侧
boolean clean_direction_both_side = cleanSystemState.getSecuWorkOnBothsidesSts();
// 纯扫 模式判断不是另外其他3个模式同时有清扫方向说明开启了纯扫模式
boolean clean_mode_pure_sweep = (clean_direction_left_side || clean_direction_right_side || clean_direction_both_side)
&& (!clean_mode_wash_sweep && !clean_mode_pure_wash && !clean_mode_pure_draw);
return clean_mode_pure_sweep;
}
/**
* 构建底盘Mock数据
*
* @return
*/
public static VehicleStateOuterClass.SweeperFuTianCleanSystemState buildSweeperFuTionCleanSystemStateMockData() {
VehicleStateOuterClass.SweeperFuTianCleanSystemState.Builder builder = VehicleStateOuterClass.SweeperFuTianCleanSystemState.newBuilder();
public static ChassisStatesOuterClass.SweeperFuTianTaskSystemStates buildSweeperFuTionCleanSystemStateMockData() {
ChassisStatesOuterClass.SweeperFuTianTaskSystemStates.Builder builder = ChassisStatesOuterClass.SweeperFuTianTaskSystemStates.newBuilder();
builder.setSecuMotWorkSts(true);
builder.setSecuModWashSts(true);
builder.setSecuWorkOnBothsidesSts(true);

View File

@@ -8,12 +8,15 @@ import android.widget.ImageView
import androidx.constraintlayout.widget.ConstraintLayout
import com.mogo.och.sweeper.R
import com.mogo.och.sweeper.bean.TaskInfoBean
import com.mogo.och.sweeper.ui.popwindow.MenuPopWindow
import kotlinx.android.synthetic.main.sweeper_current_task_info.view.*
/**
* 清扫车当前任务信息展示
*/
class SweeperCurrentTaskInfoView : ConstraintLayout {
//当前任务操作菜单
private var mTaskMenuPopWindow: MenuPopWindow? = null
constructor(context: Context) : super(context) {}
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
initView(context)
@@ -25,13 +28,11 @@ class SweeperCurrentTaskInfoView : ConstraintLayout {
private fun initView(context: Context) {
LayoutInflater.from(context).inflate(R.layout.sweeper_current_task_info, this)
}
fun getIvMore(): ImageView = ivMore
/**
* 设置当前任务数据
*/
fun setData(listTask: List<TaskInfoBean>, currentPosition: Int) {
fun setData(workModePanelView:SweeperWorkModeView,listTask: List<TaskInfoBean>, currentPosition: Int,menuItemClickListener: MenuPopWindow.OnMenuItemOnClickListener) {
mTaskMenuPopWindow = MenuPopWindow(context, menuItemClickListener)
if (listTask.size == 1) {
preSubTask.setData(listTask[currentPosition], isSelect=true,isLastTask=true)
currentSubTask.visibility = View.INVISIBLE
@@ -53,7 +54,7 @@ class SweeperCurrentTaskInfoView : ConstraintLayout {
lastSubTask.setData(listTask[2], isLastTask=true)
//当前正在执行的任务是最后一个子任务
} else if (currentPosition == listTask.size - 1) {
preSubTask.setData(listTask[currentPosition - 2], isSelect=true)
preSubTask.setData(listTask[currentPosition - 2])
currentSubTask.setData(listTask[currentPosition-1])
lastSubTask.setData(listTask[currentPosition], isSelect=true,isLastTask=true)
} else {
@@ -62,6 +63,18 @@ class SweeperCurrentTaskInfoView : ConstraintLayout {
lastSubTask.setData(listTask[currentPosition + 1],isLastTask=true)
}
}
//任务操作菜单打开关闭处理
ivMore.setOnClickListener {
if (mTaskMenuPopWindow?.isShowing != true) {
mTaskMenuPopWindow?.showAsDropDown(
workModePanelView,
resources.getDimension(R.dimen.dp_580).toInt(),
resources.getDimension(R.dimen.dp_36).toInt()
)
} else {
mTaskMenuPopWindow?.dismiss()
}
}
}
/**

View File

@@ -47,7 +47,8 @@ class SweeperTrafficLightView @JvmOverloads constructor(context: Context?, attrs
super.disableWarningTrafficLight()
UiThreadHandler.post {
mCurrentLightId = 0
mLightIconIV!!.setImageResource(R.drawable.sweeper_light_gay_nor)
mLightTimeTV?.text = ""
mLightIconIV?.setImageResource(R.drawable.sweeper_light_gay_nor)
}
}
@@ -70,9 +71,9 @@ class SweeperTrafficLightView @JvmOverloads constructor(context: Context?, attrs
super.changeCountdownRed(redNum)
UiThreadHandler.post {
if (redNum > 0) {
mLightTimeTV!!.text = redNum.toString()
mLightTimeTV?.text = redNum.toString()
} else {
mLightTimeTV!!.text = ""
mLightTimeTV?.text = ""
}
}
}
@@ -81,9 +82,9 @@ class SweeperTrafficLightView @JvmOverloads constructor(context: Context?, attrs
super.changeCountdownGreen(greenNum)
UiThreadHandler.post {
if (greenNum > 0) {
mLightTimeTV!!.text = greenNum.toString()
mLightTimeTV?.text = greenNum.toString()
} else {
mLightTimeTV!!.text = ""
mLightTimeTV?.text = ""
}
}
}
@@ -92,9 +93,9 @@ class SweeperTrafficLightView @JvmOverloads constructor(context: Context?, attrs
super.changeCountdownYellow(yellowNum)
UiThreadHandler.post {
if (yellowNum > 0) {
mLightTimeTV!!.text = yellowNum.toString()
mLightTimeTV?.text = yellowNum.toString()
} else {
mLightTimeTV!!.text = ""
mLightTimeTV?.text = ""
}
}
}
@@ -107,10 +108,10 @@ class SweeperTrafficLightView @JvmOverloads constructor(context: Context?, attrs
private fun updateTrafficLightIcon(lightId: Int) {
UiThreadHandler.post {
when (lightId) {
1 -> mLightIconIV!!.setImageResource(R.drawable.sweeper_light_red_nor)
2 -> mLightIconIV!!.setImageResource(R.drawable.sweeper_lightyellow_nor)
3 -> mLightIconIV!!.setImageResource(R.drawable.sweeper_light_green_nor)
else -> mLightIconIV!!.setImageResource(R.drawable.sweeper_light_gay_nor)
1 -> mLightIconIV?.setImageResource(R.drawable.sweeper_light_red_nor)
2 -> mLightIconIV?.setImageResource(R.drawable.sweeper_lightyellow_nor)
3 -> mLightIconIV?.setImageResource(R.drawable.sweeper_light_green_nor)
else -> mLightIconIV?.setImageResource(R.drawable.sweeper_light_gay_nor)
}
}
}

View File

@@ -3,13 +3,26 @@ package com.mogo.och.sweeper.view
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import androidx.constraintlayout.widget.ConstraintLayout
import chassis.ChassisStatesOuterClass.SweeperFuTianTaskSystemStates
import com.mogo.och.sweeper.R
import com.mogo.och.sweeper.callback.CleaningModeStateCallback
import com.mogo.och.sweeper.constant.OperateStateEnum
import com.mogo.och.sweeper.ui.popwindow.SweeperOperatePanelPopWindow
import com.mogo.och.sweeper.util.SweeperFutianCmdUtil
import kotlinx.android.synthetic.main.sweeper_work_mode.view.*
/**
* 清扫车模式信息展示
*/
class SweeperWorkModeView : ConstraintLayout {
class SweeperWorkModeView : ConstraintLayout, CleaningModeStateCallback {
private var isSelectPureSweepMode:Boolean=false
//清扫模式选择面板
private var mOperatePanelPopWindow: SweeperOperatePanelPopWindow? = null
constructor(context: Context) : super(context) {}
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
initView(context)
@@ -20,5 +33,106 @@ class SweeperWorkModeView : ConstraintLayout {
private fun initView(context: Context) {
LayoutInflater.from(context).inflate(R.layout.sweeper_work_mode, this)
mOperatePanelPopWindow = SweeperOperatePanelPopWindow(context)
}
/**
* 设置清扫模式面板
*/
fun setSweeperFutianCleanSystemState(taskType:Int,cleanSystemState: SweeperFuTianTaskSystemStates, trafficDataView: SweeperTrafficDataView) {
mOperatePanelPopWindow?.setCleanSystemState(cleanSystemState,this@SweeperWorkModeView)
//清扫模式选择面板打开关闭处理
ivOpenOperatePanel.setOnClickListener {
if (mOperatePanelPopWindow?.isShowing != true) {
mOperatePanelPopWindow?.showAsDropDown(
trafficDataView,
resources.getDimension(R.dimen.dp_600).toInt(),
0
)
} else {
mOperatePanelPopWindow?.dismiss()
}
}
//清扫车暂未选择清扫模式或者任务类型是人工驾驶子任务,则暂无清扫模式
if (SweeperFutianCmdUtil.checkIfCleanMode(cleanSystemState)||taskType==2){
setShowOrHideCleanSystemState(OperateStateEnum.NO_STATUS,cleanSystemState)
}else{
setShowOrHideCleanSystemState(OperateStateEnum.SUCCESS_STATUS,cleanSystemState)
}
}
/**
* 设置清扫模式状态显示和隐藏
*/
fun setShowOrHideCleanSystemState(operateState: OperateStateEnum,cleanSystemState: SweeperFuTianTaskSystemStates) {
when (operateState.code) {
OperateStateEnum.SYNCING_STATUS.code ->{
groupWorkModelPanel?.visibility = View.GONE
tvNoDataDesc?.visibility = View.VISIBLE
tvNoDataDesc?.text = "状态同步中,请稍后"
}
OperateStateEnum.FAIL_STATUS.code ->{
groupWorkModelPanel?.visibility = View.GONE
tvNoDataDesc?.visibility = View.VISIBLE
tvNoDataDesc?.text = "上装启动失败"
}
OperateStateEnum.STARTING_STATUS.code ->{
groupWorkModelPanel?.visibility = View.GONE
tvNoDataDesc?.visibility = View.VISIBLE
tvNoDataDesc?.text = "上装启动中..."
}
OperateStateEnum.NO_STATUS.code ->{
groupWorkModelPanel?.visibility = View.GONE
tvNoDataDesc?.visibility = View.VISIBLE
tvNoDataDesc?.text = "暂无"
}
else->{
groupWorkModelPanel?.visibility = View.VISIBLE
tvNoDataDesc?.visibility = View.GONE
setCleanModeData(cleanSystemState)
}
}
}
override fun cleaningModeState(operateState: OperateStateEnum, cleanSystemState: SweeperFuTianTaskSystemStates,isSelectPureSweepMode:Boolean) {
this.isSelectPureSweepMode=isSelectPureSweepMode
setShowOrHideCleanSystemState(operateState,cleanSystemState)
}
/**
* 设置清扫模式数据
*/
private fun setCleanModeData(cleanSystemState: SweeperFuTianTaskSystemStates){
if (SweeperFutianCmdUtil.checkIfCleanMode(cleanSystemState)){
groupWorkModelPanel?.visibility = View.GONE
tvNoDataDesc?.visibility = View.VISIBLE
tvNoDataDesc?.text = "暂无"
}else{
groupWorkModelPanel?.visibility = View.VISIBLE
tvNoDataDesc?.visibility = View.GONE
// 作业模式
if (cleanSystemState.secuModWashSweepSts) tvCleaningMode?.text = "洗扫模式"
if (cleanSystemState.secuModWashSts) tvCleaningMode?.text = "纯洗模式"
if (cleanSystemState.secuWorkTonSts) tvCleaningMode?.text = "纯吸模式"
if (SweeperFutianCmdUtil.checkIfCleanModePureSweep(cleanSystemState)||isSelectPureSweepMode) tvCleaningMode?.text = "纯扫模式"
}
//清扫方向
if(SweeperFutianCmdUtil.checkIfCleanDirection(cleanSystemState)){
tvCleaningDirection.visibility=View.GONE
}else{
tvCleaningDirection.visibility=View.VISIBLE
// 左侧
if (cleanSystemState.secuWorkLeftSts) tvCleaningDirection?.text = "左侧"
// 右侧
if (cleanSystemState.secuWorkRightSts) tvCleaningDirection?.text = "右侧"
// 两侧
if (cleanSystemState.secuWorkOnBothsidesSts) tvCleaningDirection?.text = "两侧"
}
if (SweeperFutianCmdUtil.checkIfCleanIntensity(cleanSystemState)){
tvCleaningIntensity.visibility=View.GONE
}else{
tvCleaningIntensity.visibility=View.VISIBLE
// 作业强度
if (cleanSystemState.secuWorkStandSts) tvCleaningIntensity?.text = "标准"
if (cleanSystemState.secuWorkStrongSts) tvCleaningIntensity?.text = "强力"
}
}
}

View File

@@ -1,13 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:cardBackgroundColor="@android:color/transparent"
app:cardCornerRadius="30dp"
app:cardElevation="8dp"
app:cardPreventCornerOverlap="false"
app:cardUseCompatPadding="true">
xmlns:app="http://schemas.android.com/apk/res-auto"
app:cardCornerRadius="@dimen/dp_30"
app:cardElevation="0dp"
app:cardUseCompatPadding="false">
<com.mogo.och.common.module.map.CommonAmapNaviVIew
android:id="@+id/navi_view"

View File

@@ -140,7 +140,9 @@
android:layout_width="@dimen/dp_600"
android:layout_height="@dimen/dp_600"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginEnd="@dimen/module_mogo_och_margin_right"
android:layout_marginBottom="@dimen/module_mogo_och_margin_bottom"/>
<ImageView
android:id="@+id/sweeper_close_navi_icon"
android:layout_width="@dimen/dp_80"
@@ -162,6 +164,14 @@
app:layout_constraintEnd_toEndOf="@+id/module_mogo_och_navi_panel_container"
android:src="@drawable/sweeper_navi_refresh"
/>
<androidx.constraintlayout.widget.Group
android:id="@+id/group_navi_panel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:constraint_referenced_ids="module_mogo_och_navi_panel_container,sweeper_close_navi_icon
,sweeper_refresh_navi"
tools:visibility="visible" />
<Button
android:id="@+id/btnAutopilotDisable"
android:layout_width="wrap_content"

View File

@@ -4,51 +4,6 @@
android:layout_width="@dimen/dp_957"
android:layout_height="@dimen/dp_758"
android:background="@drawable/bg_sweeper_operate_panel">
<TextView
android:id="@+id/hint_clean_work"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#ffffff"
android:gravity="top|center_horizontal"
android:paddingStart="@dimen/dp_8"
android:paddingTop="@dimen/dp_12"
android:paddingEnd="@dimen/dp_8"
android:paddingBottom="@dimen/dp_12"
android:text="车辆准备"
android:textColor="#000000"
android:textSize="@dimen/sweeper_operate_panel_btn_text_size"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:visibility="gone"/>
<CheckedTextView
android:id="@+id/btn_clean_work_open_close"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_28"
android:background="@drawable/sweeper_operate_panel_btn1_bg_selector"
android:checked="false"
android:gravity="center"
android:paddingStart="@dimen/dp_28"
android:paddingTop="@dimen/dp_12"
android:paddingEnd="@dimen/dp_28"
android:paddingBottom="@dimen/dp_12"
android:text="open"
android:minWidth="@dimen/dp_86"
android:textColor="#000000"
android:textSize="@dimen/sweeper_operate_panel_btn_text_size"
app:layout_constraintLeft_toRightOf="@id/hint_clean_work"
app:layout_constraintTop_toTopOf="@id/hint_clean_work"
android:visibility="gone"/>
<androidx.constraintlayout.widget.Barrier
android:id="@+id/clean_work_barrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="bottom"
app:constraint_referenced_ids="hint_clean_work, btn_clean_work_open_close" />
<TextView
android:id="@+id/hint_clean_mode"
android:layout_width="wrap_content"

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<com.mogo.och.sweeper.ui.SweeperOperatePanelView
android:id="@+id/SweeperOperatePanelView"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</com.mogo.och.sweeper.ui.SweeperOperatePanelView>

View File

@@ -68,7 +68,7 @@
app:layout_constraintStart_toEndOf="@+id/line1"
app:layout_constraintTop_toTopOf="@+id/sweeperTrafficPosition"
app:layout_constraintBottom_toBottomOf="@+id/sweeperTrafficPosition"
android:layout_marginStart="@dimen/dp_26"
android:layout_marginStart="@dimen/dp_28"
/>
<com.mogo.och.sweeper.view.TurnSignalView
android:id="@+id/sweeperTurnSignal"
@@ -89,12 +89,12 @@
android:background="#414869"/>
<com.mogo.och.sweeper.view.SweeperTrafficLightView
android:id="@+id/sweeperTrafficLight"
android:layout_width="@dimen/dp_170"
android:layout_height="@dimen/dp_170"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="@dimen/dp_70"
android:layout_marginEnd="@dimen/dp_6"
android:layout_marginBottom="@dimen/dp_76"
android:layout_marginEnd="@dimen/dp_12"
/>
<ImageView
android:id="@+id/sweeperIvBattery"

View File

@@ -1,14 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools">
android:layout_width="wrap_content"
android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools"
android:layout_gravity="center">
<ImageView
android:id="@+id/sweeper_traffic_light_iv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_width="@dimen/dp_155"
android:layout_height="@dimen/dp_155"
android:layout_gravity="center"
android:src="@drawable/sweeper_light_gay_nor"/>
android:src="@drawable/sweeper_light_gay_nor"
android:scaleType="fitXY"/>
<TextView
android:id="@+id/sweeper_traffic_light_time_tv"
android:layout_width="match_parent"

View File

@@ -17,53 +17,55 @@
android:textSize="@dimen/dp_32"
android:layout_marginTop="@dimen/dp_30"
android:layout_marginStart="@dimen/dp_36"/>
<TextView
android:id="@+id/tvCleaningMode"
android:layout_width="wrap_content"
<LinearLayout
android:id="@+id/groupWorkModelPanel"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@+id/tvTitle"
app:layout_constraintStart_toStartOf="@+id/tvTitle"
android:text="纯扫模式"
android:textSize="@dimen/dp_34"
android:textColor="@color/white"
android:layout_marginTop="@dimen/dp_16"
android:background="@drawable/bg_shape_clean_mode"
android:paddingStart="@dimen/dp_10"
android:paddingEnd="@dimen/dp_10"
android:paddingTop="@dimen/dp_2"
android:paddingBottom="@dimen/dp_2"/>
<TextView
android:id="@+id/tvCleaningDirection"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toEndOf="@+id/tvCleaningMode"
app:layout_constraintTop_toBottomOf="@+id/tvTitle"
android:text="左侧"
android:textSize="@dimen/dp_34"
android:textColor="@color/white"
android:layout_marginTop="@dimen/dp_16"
android:background="@drawable/bg_shape_clean_mode"
android:paddingStart="@dimen/dp_10"
android:paddingEnd="@dimen/dp_10"
android:paddingTop="@dimen/dp_2"
android:paddingBottom="@dimen/dp_2"
android:layout_marginStart="@dimen/dp_20"/>
<TextView
android:id="@+id/tvCleaningIntensity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toEndOf="@+id/tvCleaningDirection"
app:layout_constraintTop_toBottomOf="@+id/tvTitle"
android:text="标准"
android:textSize="@dimen/dp_34"
android:textColor="@color/white"
android:layout_marginTop="@dimen/dp_16"
android:background="@drawable/bg_shape_clean_mode"
android:paddingStart="@dimen/dp_10"
android:paddingEnd="@dimen/dp_10"
android:paddingTop="@dimen/dp_2"
android:paddingBottom="@dimen/dp_2"
android:layout_marginStart="@dimen/dp_20"/>
app:layout_constraintStart_toStartOf="@+id/tvTitle">
<TextView
android:id="@+id/tvCleaningMode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="纯扫模式"
android:textSize="@dimen/dp_34"
android:textColor="@color/white"
android:layout_marginTop="@dimen/dp_16"
android:background="@drawable/bg_shape_clean_mode"
android:paddingStart="@dimen/dp_10"
android:paddingEnd="@dimen/dp_10"
android:paddingTop="@dimen/dp_2"
android:paddingBottom="@dimen/dp_2"/>
<TextView
android:id="@+id/tvCleaningDirection"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="左侧"
android:textSize="@dimen/dp_34"
android:textColor="@color/white"
android:layout_marginTop="@dimen/dp_16"
android:background="@drawable/bg_shape_clean_mode"
android:paddingStart="@dimen/dp_10"
android:paddingEnd="@dimen/dp_10"
android:paddingTop="@dimen/dp_2"
android:paddingBottom="@dimen/dp_2"
android:layout_marginStart="@dimen/dp_20"/>
<TextView
android:id="@+id/tvCleaningIntensity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="标准"
android:textSize="@dimen/dp_34"
android:textColor="@color/white"
android:layout_marginTop="@dimen/dp_16"
android:background="@drawable/bg_shape_clean_mode"
android:paddingStart="@dimen/dp_10"
android:paddingEnd="@dimen/dp_10"
android:paddingTop="@dimen/dp_2"
android:paddingBottom="@dimen/dp_2"
android:layout_marginStart="@dimen/dp_20"
/>
</LinearLayout>
<ImageView
android:id="@+id/ivOpenOperatePanel"
android:layout_width="@dimen/dp_54"
@@ -80,16 +82,9 @@
app:layout_constraintTop_toBottomOf="@+id/tvTitle"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginTop="@dimen/dp_16"
android:text="暂无"
tools:text="暂无"
android:textSize="@dimen/dp_34"
android:visibility="gone"
android:textColor="@color/white"
android:layout_marginStart="@dimen/dp_36"/>
<androidx.constraintlayout.widget.Group
android:id="@+id/groupWorkModelPanel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="visible"
app:constraint_referenced_ids="tvCleaningMode,tvCleaningDirection,tvCleaningIntensity"
/>
</androidx.constraintlayout.widget.ConstraintLayout>