commit all
This commit is contained in:
+2
-3
@@ -9,8 +9,8 @@ android {
|
||||
applicationId "com.uns.maincar"
|
||||
minSdk 26
|
||||
targetSdk 32
|
||||
versionCode 25
|
||||
versionName '2.2.2'
|
||||
versionCode 30
|
||||
versionName '3.0.0'
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
externalNativeBuild {
|
||||
@@ -18,7 +18,6 @@ android {
|
||||
cppFlags ''
|
||||
}
|
||||
}
|
||||
versionNameSuffix '-beta'
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
"type": "SINGLE",
|
||||
"filters": [],
|
||||
"attributes": [],
|
||||
"versionCode": 25,
|
||||
"versionName": "2.2.2-beta",
|
||||
"versionCode": 30,
|
||||
"versionName": "3.0.0",
|
||||
"outputFile": "app-release.apk"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -38,6 +38,15 @@
|
||||
android:theme="@style/Theme.MainCar"
|
||||
android:usesCleartextTraffic="true"
|
||||
tools:targetApi="31">
|
||||
<activity
|
||||
android:name=".gui.RaceTasks"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:name=".gui.SingleFunctionTest"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:name=".gui.DebugPage"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:name=".gui.MovementController"
|
||||
android:exported="false" />
|
||||
|
||||
@@ -10,186 +10,52 @@
|
||||
|
||||
namespace uns
|
||||
{
|
||||
BinaryByteArray uns::MC_AES::CreateTextArray(std::string str)
|
||||
void MC_AES::KSA()
|
||||
{
|
||||
if (str.size() > 16)
|
||||
return nullptr;
|
||||
BinaryByteArray arr = new ByteArray[4];
|
||||
for (int i = 0; i < 4; i++)
|
||||
arr[i] = new byte[4];
|
||||
if (str.size() != 16)
|
||||
int j = 0;
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
int fix_bit = 16 - str.size();
|
||||
while (str.size() < 16)
|
||||
str.push_back(fix_bit);
|
||||
}
|
||||
for (int i = 0; i < str.size(); i += 4)
|
||||
{
|
||||
for (int j = i; j < i + 4; j++)
|
||||
arr[j - i][i / 4] = str[j];
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
word uns::MC_AES::Byte2Word(std::string str_4)
|
||||
{
|
||||
word result = 0;
|
||||
result |= ((unsigned long long)str_4[0] << 24);
|
||||
result |= ((unsigned long long)str_4[1] << 16);
|
||||
result |= ((unsigned long long)str_4[2] << 8);
|
||||
result |= str_4[3];
|
||||
return result;
|
||||
}
|
||||
|
||||
WordArray uns::MC_AES::CreateKeyArray(std::string key)
|
||||
{
|
||||
if (key.size() != 16)
|
||||
return nullptr;
|
||||
WordArray arr = new word[4];
|
||||
for (int i = 0; i < 16; i += 4)
|
||||
arr[i / 4] = Byte2Word(key.substr(i, 4));
|
||||
return arr;
|
||||
}
|
||||
|
||||
word uns::MC_AES::CircleLeft(word rw)
|
||||
{
|
||||
word high = rw << 8;
|
||||
word low = rw >> 24;
|
||||
return high | low;
|
||||
}
|
||||
|
||||
ByteArray uns::MC_AES::MoveLeft(ByteArray bytes, int bits)
|
||||
{
|
||||
if (bits == 0)
|
||||
return bytes;
|
||||
else
|
||||
{
|
||||
bits = bits % 4;
|
||||
while (bits--)
|
||||
{
|
||||
byte index = bytes[0];
|
||||
for (int i = 0; i < 3; i++)
|
||||
bytes[i] = bytes[i + 1];
|
||||
bytes[3] = index;
|
||||
}
|
||||
return bytes;
|
||||
j = (j + S[i] + K[i]) % 256;
|
||||
Swap(S[i], S[j]);
|
||||
}
|
||||
}
|
||||
|
||||
word uns::MC_AES::SubWord(word sw)
|
||||
int MC_AES::PRGA()
|
||||
{
|
||||
word temp;
|
||||
for (int i = 0; i < 32; i += 8)
|
||||
i = (i + 1) % 256;
|
||||
j = (j + S[i]) % 256;
|
||||
Swap(S[i], S[j]);
|
||||
int t = (S[i] + S[j]) % 256;
|
||||
return S[t];
|
||||
}
|
||||
|
||||
void MC_AES::Swap(int &a, int &b)
|
||||
{
|
||||
int temp = a;
|
||||
a = b;
|
||||
b = temp;
|
||||
}
|
||||
|
||||
void MC_AES::InitBox(std::string data)
|
||||
{
|
||||
int data_index = 0;
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
int row = sw[i + 7] * 8 + sw[i + 6] * 4 + sw[i + 5] * 2 + sw[i + 4];
|
||||
int col = sw[i + 3] * 8 + sw[i + 2] * 4 + sw[i + 1] * 2 + sw[i];
|
||||
byte val = S_Box[row][col];
|
||||
for (int j = 0; j < 8; ++j)
|
||||
temp[i + j] = val[j];
|
||||
S.push_back(i);
|
||||
K.push_back(data[data_index++]);
|
||||
if (data_index == data.length())
|
||||
data_index = 0;
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
WordArray uns::MC_AES::KeyExpansion(WordArray fix_key)
|
||||
Box MC_AES::Run(std::string info, std::string data)
|
||||
{
|
||||
WordArray keys = new word[44];
|
||||
for (int i = 0; i < 44; i++)
|
||||
{
|
||||
if (i < 4)
|
||||
keys[i] = fix_key[i];
|
||||
else if ((i % 4) != 0)
|
||||
keys[i] = keys[i - 4] ^ keys[i - 1];
|
||||
else
|
||||
keys[i] = keys[i - 4] ^ SubWord(CircleLeft(keys[i - 1])) ^ Rcon[(i / 4) - 1];
|
||||
}
|
||||
delete[] fix_key;
|
||||
return keys;
|
||||
}
|
||||
|
||||
BinaryByteArray uns::MC_AES::BytesReplace(BinaryByteArray bytes)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
for (int j = 0; j < 4; j++)
|
||||
{
|
||||
int row = bytes[i][j][7] * 8 + bytes[i][j][6] * 4 + bytes[i][j][5] * 2 + bytes[i][j][4];
|
||||
int col = bytes[i][j][3] * 8 + bytes[i][j][2] * 4 + bytes[i][j][1] * 2 + bytes[i][j][0];
|
||||
bytes[i][j] = S_Box[row][col];
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
BinaryByteArray uns::MC_AES::ByteShift(BinaryByteArray bytes)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
bytes[i] = MoveLeft(bytes[i], i);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
BinaryByteArray uns::MC_AES::ColumnMix(BinaryByteArray bytes)
|
||||
{
|
||||
for(int i = 0; i < 4; i++)
|
||||
for (int j = 0; j < 4; j++)
|
||||
bytes[i][j] = bytes[i][j].to_ullong() + Columns[i][j].to_ulong();
|
||||
return bytes;
|
||||
}
|
||||
|
||||
byte uns::MC_AES::SplitWord(word w, int index)
|
||||
{
|
||||
if ((index < 0) || (index >= 4))
|
||||
return 0;
|
||||
WordSpliter spliter;
|
||||
spliter._word = w.to_ullong();
|
||||
return spliter._result[index];
|
||||
}
|
||||
|
||||
WordArray uns::MC_AES::GetCurrentKeys(WordArray keys, int times)
|
||||
{
|
||||
if ((times < 0) || (times >= 10))
|
||||
return nullptr;
|
||||
WordArray result = new word[4];
|
||||
for (int i = 4; i <= 7; i++)
|
||||
result[i - 4] = keys[i + times];
|
||||
return result;
|
||||
}
|
||||
|
||||
BinaryByteArray uns::MC_AES::ColumnMix(BinaryByteArray bytes, WordArray keys)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
for (int j = 0; j < 4; j++)
|
||||
bytes[j][i] ^= SplitWord(keys[i], 3 - j).to_ullong();
|
||||
}
|
||||
delete[] keys;
|
||||
return bytes;
|
||||
}
|
||||
|
||||
ByteArray uns::MC_AES::GetAlarmCode(BinaryByteArray bytes)
|
||||
{
|
||||
WordArray wcode = new word[4];
|
||||
ByteArray bcode = new byte[6];
|
||||
memset(wcode, 0, sizeof(wcode));
|
||||
memset(bcode, 0, sizeof(bcode));
|
||||
for (int i = 0; i < 4; i++)
|
||||
for (int j = 0; j < 4; j++)
|
||||
wcode[i] = wcode[i].to_ullong() + bytes[j][i].to_ullong();
|
||||
bcode[0] = S_Box[0x0][0x0];
|
||||
bcode[1] = S_Box[0xF][0xF];
|
||||
for (int i = 0; i < 4; i++)
|
||||
bcode[i + 2] = SplitWord(wcode[i], 0);
|
||||
delete[] wcode;
|
||||
return bcode;
|
||||
}
|
||||
|
||||
ByteArray MC_AES::RunAES(std::string text, std::string key)
|
||||
{
|
||||
BinaryByteArray arr = CreateTextArray(text);
|
||||
WordArray warr = KeyExpansion(CreateKeyArray(key));
|
||||
for (int i = 0; i < 10; i++)
|
||||
arr = ColumnMix(ColumnMix(ByteShift(BytesReplace(arr))), GetCurrentKeys(warr, i));
|
||||
ByteArray code = GetAlarmCode(arr);
|
||||
delete[] arr;
|
||||
delete[] warr;
|
||||
return code;
|
||||
InitBox(data);
|
||||
KSA();
|
||||
Box password;
|
||||
for (auto &chr: info)
|
||||
password.push_back(PRGA() ^ chr);
|
||||
return password;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -206,11 +72,10 @@ jboolean JNICALL Java_com_uns_maincar_cpp_1interface_MainCarAES_RunAES(JNIEnv *e
|
||||
if(result == nullptr)
|
||||
return false;
|
||||
uns::MC_AES aes;
|
||||
uns::ByteArray arr = aes.RunAES(env->GetStringUTFChars(text, 0));
|
||||
jbyte barr[6] = { 0 };
|
||||
uns::Box arr = aes.Run("chinaskills", env->GetStringUTFChars(text, 0));
|
||||
jbyte barr[6] = {0};
|
||||
for(int i = 0; i < 6; i++)
|
||||
barr[i] = (jbyte)arr[i].to_ulong();
|
||||
barr[i] = (jbyte) arr[i];
|
||||
env->SetByteArrayRegion(result, 0, 6, barr);
|
||||
delete[] arr;
|
||||
return true;
|
||||
}
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
//数据处理算法
|
||||
|
||||
#define MAIN_CAR_AES_VERSION "1.0.0"
|
||||
#define MAIN_CAR_AES_VERSION "2.0.0"
|
||||
|
||||
#include <jni.h>
|
||||
#include <bitset>
|
||||
@@ -17,87 +17,24 @@
|
||||
|
||||
namespace uns
|
||||
{
|
||||
using byte = std::bitset<8>;
|
||||
using word = std::bitset<32>;
|
||||
|
||||
using ByteArray = byte*;
|
||||
using WordArray = word*;
|
||||
using BinaryByteArray = byte**;
|
||||
using BinaryWordArray = word**;
|
||||
|
||||
union WordSpliter
|
||||
{
|
||||
unsigned long long _word;
|
||||
char _result[4];
|
||||
};
|
||||
using Box = std::vector<int>;
|
||||
|
||||
class MC_AES
|
||||
{
|
||||
private:
|
||||
byte S_Box[16][16] =
|
||||
{
|
||||
{0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
|
||||
0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76},
|
||||
{0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
|
||||
0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0},
|
||||
{0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
|
||||
0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15},
|
||||
{0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
|
||||
0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75},
|
||||
{0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
|
||||
0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84},
|
||||
{0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
|
||||
0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF},
|
||||
{0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
|
||||
0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8},
|
||||
{0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
|
||||
0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2},
|
||||
{0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
|
||||
0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73},
|
||||
{0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
|
||||
0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB},
|
||||
{0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
|
||||
0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79},
|
||||
{0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
|
||||
0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08},
|
||||
{0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
|
||||
0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A},
|
||||
{0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
|
||||
0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E},
|
||||
{0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
|
||||
0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF},
|
||||
{0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
|
||||
0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16}
|
||||
};
|
||||
word Rcon[10] =
|
||||
{
|
||||
0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000,
|
||||
0x20000000, 0x40000000, 0x80000000, 0x1b000000, 0x36000000
|
||||
};
|
||||
byte Columns[4][4] =
|
||||
{
|
||||
{0x0E, 0x09, 0x0D, 0x0B},
|
||||
{0x0B, 0x0E, 0x0D, 0x09},
|
||||
{0x0D, 0x09, 0x0B, 0x0E},
|
||||
{0x09, 0x0D, 0x0B, 0x0E}
|
||||
};
|
||||
Box S, K;
|
||||
int i = 0, j = 0;
|
||||
private:
|
||||
BinaryByteArray CreateTextArray(std::string str);
|
||||
word Byte2Word(std::string str_4);
|
||||
WordArray CreateKeyArray(std::string key);
|
||||
word CircleLeft(word rw);
|
||||
ByteArray MoveLeft(ByteArray bytes, int bits);
|
||||
word SubWord(word sw);
|
||||
WordArray KeyExpansion(WordArray fix_key);
|
||||
BinaryByteArray BytesReplace(BinaryByteArray bytes);
|
||||
BinaryByteArray ByteShift(BinaryByteArray bytes);
|
||||
BinaryByteArray ColumnMix(BinaryByteArray bytes);
|
||||
byte SplitWord(word w, int index);
|
||||
WordArray GetCurrentKeys(WordArray keys, int times);
|
||||
BinaryByteArray ColumnMix(BinaryByteArray bytes, WordArray keys);
|
||||
ByteArray GetAlarmCode(BinaryByteArray bytes);
|
||||
void KSA();
|
||||
|
||||
int PRGA();
|
||||
|
||||
void Swap(int &a, int &b);
|
||||
|
||||
void InitBox(std::string data);
|
||||
|
||||
public:
|
||||
ByteArray RunAES(std::string text, std::string key = "abcdefghijklmnop");
|
||||
Box Run(std::string info, std::string data);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -19,11 +19,10 @@ namespace uns
|
||||
class OCRSupport
|
||||
{
|
||||
private:
|
||||
const int limit = 90;
|
||||
const int limit = 105;
|
||||
cv::Rect roi = cv::Rect(150, 60, 350, 300);
|
||||
private:
|
||||
bool PixelCheck(const cv::Vec3b &pixel);
|
||||
|
||||
public:
|
||||
cv::Mat CutImageSize(const cv::Mat &img);
|
||||
|
||||
|
||||
@@ -73,6 +73,12 @@ public class Commands
|
||||
public static byte TASK_NUMBER_7 = 0x07;
|
||||
public static byte TASK_NUMBER_8 = 0x08;
|
||||
public static byte TASK_NUMBER_9 = 0x09;
|
||||
public static byte TASK_NUMBER_10 = 0x10;
|
||||
public static byte TASK_NUMBER_11 = 0x11;
|
||||
public static byte TASK_NUMBER_12 = 0x12;
|
||||
public static byte TASK_NUMBER_13 = 0x13;
|
||||
public static byte TASK_NUMBER_14 = 0x14;
|
||||
public static byte TASK_NUMBER_15 = 0x15;
|
||||
|
||||
//全自动模式
|
||||
public static final byte RECEIVE_FULL_AUTO = (byte) 0xA0;
|
||||
|
||||
@@ -12,6 +12,7 @@ public class Flags
|
||||
//日志TAG
|
||||
public static final String CLIENT_TAG = "MAIN-CAR-CLIENT";
|
||||
public static final String CLIENT_SEND_EX = "SEND-EX-RECEIVED";
|
||||
public static final String SUB_ACTIVITY_TAG = "SUB-ACTIVITY";
|
||||
|
||||
//摄像头控制指令
|
||||
public static final int CAMERA_UP = 0;
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2023. UnknownNetworkService Group
|
||||
* This file is created by UnknownObject at 2023 - 5 - 1
|
||||
*/
|
||||
|
||||
package com.uns.maincar.gui;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.uns.maincar.R;
|
||||
import com.uns.maincar.constants.Flags;
|
||||
|
||||
public class DebugPage extends AppCompatActivity
|
||||
{
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
protected static MainActivity Parent = null; //用于调用MainActivity内函数的静态成员变量
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_debug_page);
|
||||
|
||||
if (Parent == null)
|
||||
{
|
||||
Toast.makeText(this, "Context is null!", Toast.LENGTH_SHORT).show();
|
||||
Log.e(Flags.SUB_ACTIVITY_TAG, "Context IS NULL");
|
||||
finish();
|
||||
}
|
||||
|
||||
findViewById(R.id.btn_debug_send).setOnClickListener(view -> Parent.DebugPageCallback_DebugSend());
|
||||
|
||||
findViewById(R.id.btn_send).setOnClickListener(view -> Parent.DebugPageCallback_SendByInput(this));
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@
|
||||
package com.uns.maincar.gui;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
@@ -26,8 +27,6 @@ import android.widget.Toast;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.bkrcl.control_car_video.camerautil.CameraCommandUtil;
|
||||
import com.bkrcl.control_car_video.camerautil.SearchCameraUtil;
|
||||
import com.uns.maincar.R;
|
||||
import com.uns.maincar.communication.CommandDecoder;
|
||||
import com.uns.maincar.communication.CommandEncoder;
|
||||
@@ -49,6 +48,8 @@ import com.uns.maincar.cpp_interface.TrafficSign;
|
||||
import com.uns.maincar.tools.ImageReleaser;
|
||||
import com.uns.maincar.tools.OCRDataReleaser;
|
||||
import com.uns.maincar.tools.TextFilter;
|
||||
import com.uns.maincar.tools.camera.CameraOperator;
|
||||
import com.uns.maincar.tools.camera.CameraSearcher;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
@@ -74,10 +75,8 @@ public class MainActivity extends AppCompatActivity
|
||||
private ImageView pic_received;
|
||||
//控件——存储Toast的内容,由ToastLog()进行管理
|
||||
private TextView text_toast;
|
||||
//控制主车相机
|
||||
private CameraCommandUtil cameraCommandUtil;
|
||||
//寻找主车相机
|
||||
private SearchCameraUtil searchCameraUtil = null;
|
||||
private CameraSearcher cameraSearcher = null;
|
||||
//程序状态,通过所有自检后会设置为true
|
||||
private boolean SystemStatus = false;
|
||||
//文件状态,获取到存储权限并释放完毕所有文件会设置为true
|
||||
@@ -224,7 +223,22 @@ public class MainActivity extends AppCompatActivity
|
||||
//处理二维码数据,使用从C++代码中导出的算法
|
||||
private byte[] ProcessQRData(ArrayList<String> qr_data)
|
||||
{
|
||||
return MainCarAES.CalcAES(qr_data.get(0));
|
||||
String validate_result = "";
|
||||
CommandEncoder encoder = new CommandEncoder();
|
||||
TextFilter filter = new TextFilter();
|
||||
for (String data : qr_data)
|
||||
{
|
||||
String processed_data = filter.LetterAndNumber(data);
|
||||
if (processed_data.length() > 0)
|
||||
{
|
||||
validate_result = processed_data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (validate_result.equals(""))
|
||||
return encoder.GenerateCommand(Commands.QR_FAILED, (byte) 0, (byte) 0, (byte) 0);
|
||||
else
|
||||
return MainCarAES.CalcAES(validate_result);
|
||||
}
|
||||
|
||||
//获取程序自检指令,根据自检状态返回成功或失败
|
||||
@@ -414,7 +428,7 @@ public class MainActivity extends AppCompatActivity
|
||||
private void OCRRecognizeText()
|
||||
{
|
||||
TextFilter filter = new TextFilter();
|
||||
String str = filter.NoUnderLine(filter.RemoveEmptyCharacter(OCR.DecodeImage(currImage)));
|
||||
String str = filter.ChineseOnly(filter.RemoveEmptyCharacter(OCR.DecodeImage(currImage)));
|
||||
ToastLog("OCR Result: [" + str + "]", false, true);
|
||||
byte[] b_str;
|
||||
try
|
||||
@@ -455,8 +469,8 @@ public class MainActivity extends AppCompatActivity
|
||||
return msg_str.toString();
|
||||
}
|
||||
|
||||
//向主车发送一条任务指令
|
||||
private void SendTaskCommand(byte task_cmd)
|
||||
//向主车发送一条任务指令(改为protected允许类外调用)
|
||||
protected void SendTaskCommand(byte task_cmd)
|
||||
{
|
||||
CommandEncoder encoder = new CommandEncoder();
|
||||
Thread th_send = new Thread(() ->
|
||||
@@ -469,21 +483,140 @@ public class MainActivity extends AppCompatActivity
|
||||
th_send.start();
|
||||
}
|
||||
|
||||
//初始化比赛任务按钮
|
||||
private void InitTaskButton()
|
||||
/*
|
||||
以下protected函数用于在主界面外允许对主界面功能的调用,利用静态MainActivity对象绕过Android对不同Activity间函数调用的限制
|
||||
此操(mo)作(fa)仅用于实现UI分离和操作逻辑优化,与实际功能代码无关。
|
||||
*/
|
||||
//----------------------------------------由此处开始----------------------------------------
|
||||
//用于调试页面的发送调试信息函数
|
||||
protected void DebugPageCallback_DebugSend()
|
||||
{
|
||||
findViewById(R.id.btn_task_0).setOnClickListener(view -> SendTaskCommand(Commands.TASK_NUMBER_0));
|
||||
findViewById(R.id.btn_task_1).setOnClickListener(view -> SendTaskCommand(Commands.TASK_NUMBER_1));
|
||||
findViewById(R.id.btn_task_2).setOnClickListener(view -> SendTaskCommand(Commands.TASK_NUMBER_2));
|
||||
findViewById(R.id.btn_task_3).setOnClickListener(view -> SendTaskCommand(Commands.TASK_NUMBER_3));
|
||||
findViewById(R.id.btn_task_4).setOnClickListener(view -> SendTaskCommand(Commands.TASK_NUMBER_4));
|
||||
findViewById(R.id.btn_task_5).setOnClickListener(view -> SendTaskCommand(Commands.TASK_NUMBER_5));
|
||||
findViewById(R.id.btn_task_6).setOnClickListener(view -> SendTaskCommand(Commands.TASK_NUMBER_6));
|
||||
findViewById(R.id.btn_task_7).setOnClickListener(view -> SendTaskCommand(Commands.TASK_NUMBER_7));
|
||||
findViewById(R.id.btn_task_8).setOnClickListener(view -> SendTaskCommand(Commands.TASK_NUMBER_8));
|
||||
findViewById(R.id.btn_task_9).setOnClickListener(view -> SendTaskCommand(Commands.TASK_NUMBER_9));
|
||||
byte[] data = new byte[]{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
|
||||
dtc_client.ThreadSend(data);
|
||||
}
|
||||
|
||||
//用于调试页面的发送调试信息函数
|
||||
protected void DebugPageCallback_SendByInput(Activity context)
|
||||
{
|
||||
try
|
||||
{
|
||||
byte cmd0 = (byte) Integer.parseInt(((EditText) context.findViewById(R.id.edit_cmd0)).getText().toString(), 16);
|
||||
byte cmd1 = (byte) Integer.parseInt(((EditText) context.findViewById(R.id.edit_cmd1)).getText().toString(), 16);
|
||||
byte cmd2 = (byte) Integer.parseInt(((EditText) context.findViewById(R.id.edit_cmd2)).getText().toString(), 16);
|
||||
byte cmd3 = (byte) Integer.parseInt(((EditText) context.findViewById(R.id.edit_cmd3)).getText().toString(), 16);
|
||||
CommandEncoder encoder = new CommandEncoder();
|
||||
byte[] cmd = encoder.GenerateCommand(cmd0, cmd1, cmd2, cmd3);
|
||||
dtc_client.ThreadSend(cmd);
|
||||
//print debug information
|
||||
Message.obtain(recvHandler, Flags.PRINT_DATA_ARRAY, cmd).sendToTarget();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ToastLog("Input Data Invalidate", true, false);
|
||||
}
|
||||
}
|
||||
|
||||
//提供给单元测试页面用于初始化按钮的回调函数
|
||||
protected void InitSingleFunctionTestUnit(Activity context)
|
||||
{
|
||||
context.findViewById(R.id.btn_camera_up).setOnClickListener(view ->
|
||||
{
|
||||
Thread th_send = new Thread(() ->
|
||||
{
|
||||
if (!CameraOperator.SendCommand(IPCamera, Flags.CAMERA_UP, 5))
|
||||
ToastLog("Camera Command (UP) Failure.", false, true);
|
||||
});
|
||||
th_send.start();
|
||||
});
|
||||
|
||||
context.findViewById(R.id.btn_camera_down).setOnClickListener(view ->
|
||||
{
|
||||
Thread th_send = new Thread(() ->
|
||||
{
|
||||
if (!CameraOperator.SendCommand(IPCamera, Flags.CAMERA_DOWN, 5))
|
||||
ToastLog("Camera Command (DOWN) Failure.", false, true);
|
||||
});
|
||||
th_send.start();
|
||||
});
|
||||
|
||||
context.findViewById(R.id.btn_camera_left).setOnClickListener(view ->
|
||||
{
|
||||
Thread th_send = new Thread(() ->
|
||||
{
|
||||
if (!CameraOperator.SendCommand(IPCamera, Flags.CAMERA_LEFT, 5))
|
||||
ToastLog("Camera Command (LEFT) Failure.", false, true);
|
||||
});
|
||||
th_send.start();
|
||||
});
|
||||
|
||||
context.findViewById(R.id.btn_camera_right).setOnClickListener(view ->
|
||||
{
|
||||
Thread th_send = new Thread(() ->
|
||||
{
|
||||
if (!CameraOperator.SendCommand(IPCamera, Flags.CAMERA_RIGHT, 5))
|
||||
ToastLog("Camera Command (RIGHT) Failure.", false, true);
|
||||
});
|
||||
th_send.start();
|
||||
});
|
||||
|
||||
context.findViewById(R.id.btn_start_qr).setOnClickListener(view ->
|
||||
{
|
||||
ToastLog("QR Code Started", false, false);
|
||||
ToastLog("QR Result: " + ByteArray2String(RecognizeQrCode()), false, false);
|
||||
});
|
||||
|
||||
context.findViewById(R.id.btn_start_light).setOnClickListener(view ->
|
||||
{
|
||||
ToastLog("Traffic Light Started", false, false);
|
||||
ToastLog("TL Result: " + ByteArray2String(RecognizeTrafficLight()), false, false);
|
||||
});
|
||||
|
||||
context.findViewById(R.id.btn_start_color_shape).setOnClickListener(view ->
|
||||
{
|
||||
ToastLog("Color Shape Started", false, false);
|
||||
ToastLog("CS Result: " + ByteArray2String(RecognizeShapeColor()), false, false);
|
||||
});
|
||||
|
||||
context.findViewById(R.id.btn_start_car_id).setOnClickListener(view ->
|
||||
{
|
||||
ToastLog("Car ID Started", false, false);
|
||||
Thread th_debug = new Thread(this::RecognizeCarID);
|
||||
th_debug.start();
|
||||
ToastLog("CID Finished", false, false);
|
||||
});
|
||||
|
||||
context.findViewById(R.id.btn_start_sign).setOnClickListener(view ->
|
||||
{
|
||||
ToastLog("Traffic Sign Started", false, false);
|
||||
ToastLog("TS Result: " + ByteArray2String(RecognizeTrafficSign()), false, false);
|
||||
});
|
||||
|
||||
context.findViewById(R.id.btn_start_ocr).setOnClickListener(view ->
|
||||
{
|
||||
ToastLog("OCR Started", false, false);
|
||||
Thread th_debug = new Thread(this::OCRRecognizeText);
|
||||
th_debug.start();
|
||||
});
|
||||
|
||||
context.findViewById(R.id.btn_tft_page_down).setOnClickListener(view ->
|
||||
{
|
||||
CommandEncoder encoder = new CommandEncoder();
|
||||
dtc_client.ThreadSend(encoder.GenerateCommand(Commands.TFT_PAGE_DOWN, (byte) 0, (byte) 0, (byte) 0));
|
||||
ToastLog("TFT Page Down Command Send.", false, true);
|
||||
});
|
||||
|
||||
context.findViewById(R.id.btn_movement_control).setOnClickListener(view -> startActivity(new Intent(this, MovementController.class)));
|
||||
|
||||
context.findViewById(R.id.btn_crash).setOnClickListener(view ->
|
||||
{
|
||||
//崩溃按钮的作用:频繁调试时省去手动退出程序,清理后台的操作,节省时间。
|
||||
dtc_client.DisableAutoReconnect();
|
||||
dtc_client.CloseConnection(); //关闭通信
|
||||
throw new NullPointerException(); //通过异常来崩溃。
|
||||
});
|
||||
}
|
||||
//----------------------------------------到此处终止----------------------------------------
|
||||
|
||||
//初始化图形界面
|
||||
private void InitGUI()
|
||||
{
|
||||
@@ -492,113 +625,29 @@ public class MainActivity extends AppCompatActivity
|
||||
|
||||
text_toast.setMovementMethod(ScrollingMovementMethod.getInstance());
|
||||
|
||||
findViewById(R.id.btn_debug_send).setOnClickListener(view ->
|
||||
findViewById(R.id.btn_debug_page).setOnClickListener(view ->
|
||||
{
|
||||
byte[] data = new byte[]{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
|
||||
dtc_client.ThreadSend(data);
|
||||
DebugPage.Parent = this;
|
||||
startActivity(new Intent(this, DebugPage.class));
|
||||
});
|
||||
|
||||
findViewById(R.id.btn_camera_up).setOnClickListener(view ->
|
||||
findViewById(R.id.btn_function_test).setOnClickListener(view ->
|
||||
{
|
||||
Thread th_send = new Thread(() -> cameraCommandUtil.postHttp(IPCamera, Flags.CAMERA_UP, 5));
|
||||
th_send.start();
|
||||
SingleFunctionTest.Parent = this;
|
||||
startActivity(new Intent(this, SingleFunctionTest.class));
|
||||
});
|
||||
|
||||
findViewById(R.id.btn_camera_down).setOnClickListener(view ->
|
||||
findViewById(R.id.btn_race_tasks).setOnClickListener(view ->
|
||||
{
|
||||
Thread th_send = new Thread(() -> cameraCommandUtil.postHttp(IPCamera, Flags.CAMERA_DOWN, 5));
|
||||
th_send.start();
|
||||
RaceTasks.Parent = this;
|
||||
startActivity(new Intent(this, RaceTasks.class));
|
||||
});
|
||||
|
||||
findViewById(R.id.btn_camera_left).setOnClickListener(view ->
|
||||
findViewById(R.id.btn_program_exit).setOnClickListener(view ->
|
||||
{
|
||||
Thread th_send = new Thread(() -> cameraCommandUtil.postHttp(IPCamera, Flags.CAMERA_LEFT, 5));
|
||||
th_send.start();
|
||||
});
|
||||
|
||||
findViewById(R.id.btn_camera_right).setOnClickListener(view ->
|
||||
{
|
||||
Thread th_send = new Thread(() -> cameraCommandUtil.postHttp(IPCamera, Flags.CAMERA_RIGHT, 5));
|
||||
th_send.start();
|
||||
});
|
||||
|
||||
findViewById(R.id.btn_send).setOnClickListener(view ->
|
||||
{
|
||||
try
|
||||
{
|
||||
byte cmd0 = (byte) Integer.parseInt(((EditText) findViewById(R.id.edit_cmd0)).getText().toString(), 16);
|
||||
byte cmd1 = (byte) Integer.parseInt(((EditText) findViewById(R.id.edit_cmd1)).getText().toString(), 16);
|
||||
byte cmd2 = (byte) Integer.parseInt(((EditText) findViewById(R.id.edit_cmd2)).getText().toString(), 16);
|
||||
byte cmd3 = (byte) Integer.parseInt(((EditText) findViewById(R.id.edit_cmd3)).getText().toString(), 16);
|
||||
CommandEncoder encoder = new CommandEncoder();
|
||||
byte[] cmd = encoder.GenerateCommand(cmd0, cmd1, cmd2, cmd3);
|
||||
dtc_client.ThreadSend(cmd);
|
||||
//print debug information
|
||||
Message.obtain(recvHandler, Flags.PRINT_DATA_ARRAY, cmd).sendToTarget();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ToastLog("Input Data Invalidate", true, false);
|
||||
}
|
||||
});
|
||||
|
||||
findViewById(R.id.btn_start_qr).setOnClickListener(view ->
|
||||
{
|
||||
ToastLog("QR Code Started", false, false);
|
||||
ToastLog("QR Result: " + ByteArray2String(RecognizeQrCode()), false, false);
|
||||
});
|
||||
|
||||
findViewById(R.id.btn_start_light).setOnClickListener(view ->
|
||||
{
|
||||
ToastLog("Traffic Light Started", false, false);
|
||||
ToastLog("TL Result: " + ByteArray2String(RecognizeTrafficLight()), false, false);
|
||||
});
|
||||
|
||||
findViewById(R.id.btn_start_color_shape).setOnClickListener(view ->
|
||||
{
|
||||
ToastLog("Color Shape Started", false, false);
|
||||
ToastLog("CS Result: " + ByteArray2String(RecognizeShapeColor()), false, false);
|
||||
});
|
||||
|
||||
findViewById(R.id.btn_start_car_id).setOnClickListener(view ->
|
||||
{
|
||||
ToastLog("Car ID Started", false, false);
|
||||
Thread th_debug = new Thread(this::RecognizeCarID);
|
||||
th_debug.start();
|
||||
ToastLog("CID Finished", false, false);
|
||||
});
|
||||
|
||||
findViewById(R.id.btn_start_sign).setOnClickListener(view ->
|
||||
{
|
||||
ToastLog("Traffic Sign Started", false, false);
|
||||
ToastLog("TS Result: " + ByteArray2String(RecognizeTrafficSign()), false, false);
|
||||
});
|
||||
|
||||
findViewById(R.id.btn_start_ocr).setOnClickListener(view ->
|
||||
{
|
||||
ToastLog("OCR Started", false, false);
|
||||
Thread th_debug = new Thread(this::OCRRecognizeText);
|
||||
th_debug.start();
|
||||
});
|
||||
|
||||
findViewById(R.id.btn_tft_page_down).setOnClickListener(view ->
|
||||
{
|
||||
CommandEncoder encoder = new CommandEncoder();
|
||||
dtc_client.ThreadSend(encoder.GenerateCommand(Commands.TFT_PAGE_DOWN, (byte) 0, (byte) 0, (byte) 0));
|
||||
ToastLog("TFT Page Down Command Send.", false, true);
|
||||
});
|
||||
|
||||
findViewById(R.id.btn_movement_control).setOnClickListener(view ->
|
||||
{
|
||||
startActivity(new Intent(this, MovementController.class));
|
||||
});
|
||||
|
||||
findViewById(R.id.btn_crash).setOnClickListener(view ->
|
||||
{
|
||||
//崩溃按钮的作用:频繁调试时省去手动退出程序,清理后台的操作,节省时间。
|
||||
dtc_client.DisableAutoReconnect();
|
||||
dtc_client.CloseConnection(); //关闭通信
|
||||
throw new NullPointerException(); //通过异常来崩溃。
|
||||
System.exit(0);
|
||||
});
|
||||
|
||||
findViewById(R.id.text_toast).setOnLongClickListener(view ->
|
||||
@@ -617,8 +666,6 @@ public class MainActivity extends AppCompatActivity
|
||||
ToastLog("Image Save Failure", true, false);
|
||||
return true;
|
||||
});
|
||||
|
||||
InitTaskButton();
|
||||
}
|
||||
|
||||
//打印日志
|
||||
@@ -650,14 +697,14 @@ public class MainActivity extends AppCompatActivity
|
||||
}
|
||||
}
|
||||
|
||||
//启动寻找摄像头的线程
|
||||
//启动获取摄像头拍摄到的图片的线程
|
||||
private void StartCameraImageUpdate(int duration)
|
||||
{
|
||||
Thread th_image = new Thread(() ->
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
currImage = cameraCommandUtil.httpForImage(IPCamera);
|
||||
currImage = CameraOperator.GetImage(IPCamera);
|
||||
recvHandler.sendEmptyMessage(Flags.RECEIVED_IMAGE);
|
||||
Sleep(duration);
|
||||
}
|
||||
@@ -723,29 +770,20 @@ public class MainActivity extends AppCompatActivity
|
||||
Sleep(10); //Wait for Connection Thread
|
||||
dtc_client.EnableAutoReconnect(); //启动自动重连
|
||||
|
||||
//初始化摄像头控制
|
||||
cameraCommandUtil = new CameraCommandUtil();
|
||||
ToastLog("CameraCommandUtil Ready.", false, false);
|
||||
|
||||
//寻找摄像头,获取其IP地址
|
||||
Thread camera_thread = new Thread(() ->
|
||||
{
|
||||
IPCamera = null;
|
||||
boolean success;
|
||||
ToastLog("CameraSearchThread: Camera Thread Start", false, true);
|
||||
while (IPCamera == null || IPCamera.equals(""))
|
||||
cameraSearcher = new CameraSearcher();
|
||||
do
|
||||
{
|
||||
searchCameraUtil = new SearchCameraUtil();
|
||||
try
|
||||
{
|
||||
IPCamera = searchCameraUtil.send();
|
||||
}
|
||||
catch (NullPointerException e)
|
||||
{
|
||||
IPCamera = null;
|
||||
}
|
||||
success = cameraSearcher.SearchOnce();
|
||||
}
|
||||
while (!success); //避免”while循环具有空体“警告
|
||||
IPCamera = cameraSearcher.GetCameraIP();
|
||||
ToastLog("CameraSearchThread: Camera Found. IP: " + IPCamera, false, true);
|
||||
IPCamera = IPCamera + ":81";
|
||||
IPCamera += ":81";
|
||||
ToastLog("Camera Address: " + IPCamera, false, true);
|
||||
StartCameraImageUpdate(50);
|
||||
//这里是程序初始化的最后一步,能到达此处标志着自检通过
|
||||
@@ -786,7 +824,5 @@ public class MainActivity extends AppCompatActivity
|
||||
//Activity销毁时关闭通信
|
||||
dtc_client.DisableAutoReconnect();
|
||||
dtc_client.CloseConnection();
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2023. UnknownNetworkService Group
|
||||
* This file is created by UnknownObject at 2023 - 5 - 1
|
||||
*/
|
||||
|
||||
package com.uns.maincar.gui;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.uns.maincar.R;
|
||||
import com.uns.maincar.constants.Commands;
|
||||
import com.uns.maincar.constants.Flags;
|
||||
|
||||
public class RaceTasks extends AppCompatActivity
|
||||
{
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
protected static MainActivity Parent = null; //用于调用MainActivity内函数的静态成员变量
|
||||
|
||||
//初始化比赛任务按钮
|
||||
private void InitTaskButton()
|
||||
{
|
||||
findViewById(R.id.btn_task_0).setOnClickListener(view -> Parent.SendTaskCommand(Commands.TASK_NUMBER_0));
|
||||
findViewById(R.id.btn_task_1).setOnClickListener(view -> Parent.SendTaskCommand(Commands.TASK_NUMBER_1));
|
||||
findViewById(R.id.btn_task_2).setOnClickListener(view -> Parent.SendTaskCommand(Commands.TASK_NUMBER_2));
|
||||
findViewById(R.id.btn_task_3).setOnClickListener(view -> Parent.SendTaskCommand(Commands.TASK_NUMBER_3));
|
||||
findViewById(R.id.btn_task_4).setOnClickListener(view -> Parent.SendTaskCommand(Commands.TASK_NUMBER_4));
|
||||
findViewById(R.id.btn_task_5).setOnClickListener(view -> Parent.SendTaskCommand(Commands.TASK_NUMBER_5));
|
||||
findViewById(R.id.btn_task_6).setOnClickListener(view -> Parent.SendTaskCommand(Commands.TASK_NUMBER_6));
|
||||
findViewById(R.id.btn_task_7).setOnClickListener(view -> Parent.SendTaskCommand(Commands.TASK_NUMBER_7));
|
||||
findViewById(R.id.btn_task_8).setOnClickListener(view -> Parent.SendTaskCommand(Commands.TASK_NUMBER_8));
|
||||
findViewById(R.id.btn_task_9).setOnClickListener(view -> Parent.SendTaskCommand(Commands.TASK_NUMBER_9));
|
||||
findViewById(R.id.btn_task_10).setOnClickListener(view -> Parent.SendTaskCommand(Commands.TASK_NUMBER_10));
|
||||
findViewById(R.id.btn_task_11).setOnClickListener(view -> Parent.SendTaskCommand(Commands.TASK_NUMBER_11));
|
||||
findViewById(R.id.btn_task_12).setOnClickListener(view -> Parent.SendTaskCommand(Commands.TASK_NUMBER_12));
|
||||
/*findViewById(R.id.btn_task_13).setOnClickListener(view -> Parent.SendTaskCommand(Commands.TASK_NUMBER_13));
|
||||
findViewById(R.id.btn_task_14).setOnClickListener(view -> Parent.SendTaskCommand(Commands.TASK_NUMBER_14));
|
||||
findViewById(R.id.btn_task_15).setOnClickListener(view -> Parent.SendTaskCommand(Commands.TASK_NUMBER_15));*/
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_race_tasks);
|
||||
|
||||
if (Parent == null)
|
||||
{
|
||||
Toast.makeText(this, "Context is null!", Toast.LENGTH_SHORT).show();
|
||||
Log.e(Flags.SUB_ACTIVITY_TAG, "Context IS NULL");
|
||||
finish();
|
||||
}
|
||||
|
||||
InitTaskButton();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2023. UnknownNetworkService Group
|
||||
* This file is created by UnknownObject at 2023 - 5 - 1
|
||||
*/
|
||||
|
||||
package com.uns.maincar.gui;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.uns.maincar.R;
|
||||
import com.uns.maincar.constants.Flags;
|
||||
|
||||
public class SingleFunctionTest extends AppCompatActivity
|
||||
{
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
protected static MainActivity Parent = null; //用于调用MainActivity内函数的静态成员变量
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_single_function_test);
|
||||
|
||||
if (Parent == null)
|
||||
{
|
||||
Toast.makeText(this, "Context is null!", Toast.LENGTH_SHORT).show();
|
||||
Log.e(Flags.SUB_ACTIVITY_TAG, "Context IS NULL");
|
||||
finish();
|
||||
}
|
||||
|
||||
Parent.InitSingleFunctionTestUnit(this);
|
||||
}
|
||||
}
|
||||
@@ -53,4 +53,15 @@ public class TextFilter
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
public String ChineseOnly(String src)
|
||||
{
|
||||
StringBuilder result = new StringBuilder();
|
||||
for (int i = 0; i < src.length(); i++)
|
||||
{
|
||||
if (src.charAt(i) > 1500)
|
||||
result.append(src.charAt(i));
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2023. UnknownNetworkService Group
|
||||
* This file is created by UnknownObject at 2023 - 5 - 1
|
||||
*/
|
||||
|
||||
package com.uns.maincar.tools.camera;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
|
||||
/*
|
||||
重写声明:
|
||||
此类由UnknownObject重写自BKRC官方库:CameraCommandUtil(camerautil.jar)。
|
||||
”BKRC官方写的都是什么辣鸡代码啊“
|
||||
————UnknownObject
|
||||
*/
|
||||
|
||||
public class CameraOperator
|
||||
{
|
||||
public static Bitmap GetImage(String IP)
|
||||
{
|
||||
try
|
||||
{
|
||||
URL url = new URL("http://" + IP + "/snapshot.cgi?loginuse=admin&loginpas=888888&res=0");
|
||||
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
|
||||
httpURLConnection.setDoInput(true);
|
||||
httpURLConnection.connect();
|
||||
InputStream in = httpURLConnection.getInputStream();
|
||||
Bitmap bitmap = BitmapFactory.decodeStream(in);
|
||||
in.close();
|
||||
httpURLConnection.disconnect();
|
||||
return bitmap;
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean SendCommand(String IP, int command, int step)
|
||||
{
|
||||
if ((command < 0) || (step < 0))
|
||||
return false;
|
||||
try
|
||||
{
|
||||
URL url = new URL("http://" + IP + "/decoder_control.cgi?loginuse=admin&loginpas=888888&" + "command=" + command + "&onestep=" + step);
|
||||
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
|
||||
urlConnection.connect();
|
||||
urlConnection.disconnect();
|
||||
return true;
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 2023. UnknownNetworkService Group
|
||||
* This file is created by UnknownObject at 2023 - 5 - 1
|
||||
*/
|
||||
|
||||
package com.uns.maincar.tools.camera;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.InetAddress;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/*
|
||||
重写声明:
|
||||
此类由UnknownObject重写自BKRC官方库:SearchCameraUtil(camerautil.jar)。
|
||||
”BKRC官方写的都是什么辣鸡代码啊“
|
||||
————UnknownObject
|
||||
*/
|
||||
|
||||
public class CameraSearcher
|
||||
{
|
||||
private String IP = "";
|
||||
private final int PORT = 3565;
|
||||
private final int SERVER_PORT = 8600;
|
||||
private DatagramSocket socket = null;
|
||||
private final byte[] recv = new byte[1024];
|
||||
private final byte[] pkt_msg = new byte[]{68, 72, 1, 1};
|
||||
|
||||
public CameraSearcher()
|
||||
{
|
||||
}
|
||||
|
||||
private void DecodeIP(String text)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder("");
|
||||
byte[] ip_byte = text.getBytes(StandardCharsets.UTF_8);
|
||||
for (int i = 4; (i < 22) && (ip_byte[i] != 0); ++i)
|
||||
{
|
||||
if (ip_byte[i] == 46)
|
||||
sb.append('.');
|
||||
else
|
||||
sb.append((ip_byte[i] - 48));
|
||||
}
|
||||
IP = sb.toString();
|
||||
}
|
||||
|
||||
public boolean SearchOnce()
|
||||
{
|
||||
try
|
||||
{
|
||||
InetAddress local = InetAddress.getByName("255.255.255.255");
|
||||
if (socket != null)
|
||||
{
|
||||
socket.close();
|
||||
socket = null;
|
||||
}
|
||||
socket = new DatagramSocket(PORT);
|
||||
DatagramPacket sendPacket = new DatagramPacket(pkt_msg, 4, local, SERVER_PORT);
|
||||
DatagramPacket recvPacket = new DatagramPacket(recv, recv.length);
|
||||
socket.send(sendPacket);
|
||||
socket.receive(recvPacket);
|
||||
String text = new String(recv, 0, recvPacket.getLength());
|
||||
socket.close();
|
||||
if (text.startsWith("DH"))
|
||||
{
|
||||
DecodeIP(text);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public String GetCameraIP()
|
||||
{
|
||||
return IP;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2023. UnknownNetworkService Group
|
||||
~ This file is created by UnknownObject at 2023 - 5 - 1
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:context=".gui.DebugPage">
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_debug_send"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="3dp"
|
||||
android:layout_marginRight="3dp"
|
||||
android:text="测试——发送一组测试数据"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/edit_cmd0"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:ems="10"
|
||||
android:hint="主指令"
|
||||
android:inputType="textPersonName"
|
||||
android:minHeight="48dp"
|
||||
tools:ignore="SpeakableTextPresentCheck" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/edit_cmd1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:ems="10"
|
||||
android:hint="数据1"
|
||||
android:inputType="textPersonName"
|
||||
android:minHeight="48dp"
|
||||
tools:ignore="SpeakableTextPresentCheck" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/edit_cmd2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:ems="10"
|
||||
android:hint="数据2"
|
||||
android:inputType="textPersonName"
|
||||
android:minHeight="48dp"
|
||||
tools:ignore="SpeakableTextPresentCheck" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/edit_cmd3"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:ems="10"
|
||||
android:hint="数据3"
|
||||
android:inputType="textPersonName"
|
||||
android:minHeight="48dp"
|
||||
tools:ignore="SpeakableTextPresentCheck" />
|
||||
</LinearLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_send"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="发送数据" />
|
||||
</LinearLayout>
|
||||
@@ -4,389 +4,53 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:context=".gui.MainActivity" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:text="主车远端服务程序"
|
||||
android:textAlignment="center"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="20sp" />
|
||||
tools:context=".gui.MainActivity">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/camera_image"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="108dp"
|
||||
android:layout_height="200dp"
|
||||
app:srcCompat="@drawable/ic_launcher_background" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_debug_send"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="3dp"
|
||||
android:layout_marginRight="3dp"
|
||||
android:text="测试——发送一组测试数据"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/edit_cmd0"
|
||||
<Button
|
||||
android:id="@+id/btn_debug_page"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="4dp"
|
||||
android:layout_weight="1"
|
||||
android:ems="10"
|
||||
android:hint="主指令"
|
||||
android:inputType="textPersonName"
|
||||
android:minHeight="48dp"
|
||||
tools:ignore="SpeakableTextPresentCheck" />
|
||||
android:text="调试页面" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/edit_cmd1"
|
||||
<Button
|
||||
android:id="@+id/btn_function_test"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="4dp"
|
||||
android:layout_weight="1"
|
||||
android:ems="10"
|
||||
android:hint="数据1"
|
||||
android:inputType="textPersonName"
|
||||
android:minHeight="48dp"
|
||||
tools:ignore="SpeakableTextPresentCheck" />
|
||||
android:text="功能测试" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/edit_cmd2"
|
||||
<Button
|
||||
android:id="@+id/btn_race_tasks"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="4dp"
|
||||
android:layout_weight="1"
|
||||
android:ems="10"
|
||||
android:hint="数据2"
|
||||
android:inputType="textPersonName"
|
||||
android:minHeight="48dp"
|
||||
tools:ignore="SpeakableTextPresentCheck" />
|
||||
android:text="比赛任务" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/edit_cmd3"
|
||||
<Button
|
||||
android:id="@+id/btn_program_exit"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="4dp"
|
||||
android:layout_weight="1"
|
||||
android:ems="10"
|
||||
android:hint="数据3"
|
||||
android:inputType="textPersonName"
|
||||
android:minHeight="48dp"
|
||||
tools:ignore="SpeakableTextPresentCheck" />
|
||||
android:text="退出程序" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_send"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="发送数据" />
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="170dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_camera_up"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="3dp"
|
||||
android:layout_marginRight="3dp"
|
||||
android:layout_weight="1"
|
||||
android:paddingLeft="10dp"
|
||||
android:paddingRight="10dp"
|
||||
android:text="摄像头\n向上" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_camera_down"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="3dp"
|
||||
android:layout_marginRight="3dp"
|
||||
android:layout_weight="1"
|
||||
android:paddingLeft="10dp"
|
||||
android:paddingRight="10dp"
|
||||
android:text="摄像头\n向下" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_camera_left"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="3dp"
|
||||
android:layout_marginRight="3dp"
|
||||
android:layout_weight="1"
|
||||
android:paddingLeft="10dp"
|
||||
android:paddingRight="10dp"
|
||||
android:text="摄像头\n向左" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_camera_right"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="3dp"
|
||||
android:layout_marginRight="3dp"
|
||||
android:layout_weight="1"
|
||||
android:paddingLeft="10dp"
|
||||
android:paddingRight="10dp"
|
||||
android:text="摄像头\n向右" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_start_qr"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="2dp"
|
||||
android:layout_weight="1"
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:paddingHorizontal="2dp"
|
||||
android:paddingLeft="0dp"
|
||||
android:paddingTop="0dp"
|
||||
android:paddingRight="0dp"
|
||||
android:paddingBottom="0dp"
|
||||
android:text="二维码识别" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_start_light"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="2dp"
|
||||
android:layout_weight="1"
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:paddingHorizontal="2dp"
|
||||
android:paddingLeft="0dp"
|
||||
android:paddingTop="0dp"
|
||||
android:paddingRight="0dp"
|
||||
android:paddingBottom="0dp"
|
||||
android:text="交通灯识别" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_start_color_shape"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="2dp"
|
||||
android:layout_weight="1"
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:paddingHorizontal="2dp"
|
||||
android:paddingLeft="0dp"
|
||||
android:paddingTop="0dp"
|
||||
android:paddingRight="0dp"
|
||||
android:paddingBottom="0dp"
|
||||
android:text="形状颜色识别" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_start_car_id"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="2dp"
|
||||
android:layout_weight="1"
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:paddingHorizontal="2dp"
|
||||
android:paddingLeft="0dp"
|
||||
android:paddingTop="0dp"
|
||||
android:paddingRight="0dp"
|
||||
android:paddingBottom="0dp"
|
||||
android:text="车牌识别" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_start_sign"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="2dp"
|
||||
android:layout_weight="1"
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:paddingHorizontal="2dp"
|
||||
android:paddingLeft="0dp"
|
||||
android:paddingTop="0dp"
|
||||
android:paddingRight="0dp"
|
||||
android:paddingBottom="0dp"
|
||||
android:text="交通标志识别" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_start_ocr"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="2dp"
|
||||
android:layout_weight="1"
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:paddingHorizontal="2dp"
|
||||
android:paddingLeft="0dp"
|
||||
android:paddingTop="0dp"
|
||||
android:paddingRight="0dp"
|
||||
android:paddingBottom="0dp"
|
||||
android:text="OCR" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_tft_page_down"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="3dp"
|
||||
android:text="TFT下翻一页" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_movement_control"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="3dp"
|
||||
android:layout_weight="1"
|
||||
android:text="移动控制" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_crash"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="3dp"
|
||||
android:layout_weight="1"
|
||||
android:text="立即崩溃" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_task_0"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="2dp"
|
||||
android:layout_weight="1"
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:text="任务0" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_task_1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="2dp"
|
||||
android:layout_weight="1"
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:text="任务1" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_task_2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="2dp"
|
||||
android:layout_weight="1"
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:text="任务2" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_task_3"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="2dp"
|
||||
android:layout_weight="1"
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:text="任务3" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_task_4"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="2dp"
|
||||
android:layout_weight="1"
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:text="任务4" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_task_5"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="2dp"
|
||||
android:layout_weight="1"
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:text="任务5" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_task_6"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="2dp"
|
||||
android:layout_weight="1"
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:text="任务6" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_task_7"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="2dp"
|
||||
android:layout_weight="1"
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:text="任务7" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_task_8"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="2dp"
|
||||
android:layout_weight="1"
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:text="任务8" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_task_9"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="2dp"
|
||||
android:layout_weight="1"
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:text="任务9" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_toast"
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2023. UnknownNetworkService Group
|
||||
~ This file is created by UnknownObject at 2023 - 5 - 1
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:context=".gui.RaceTasks">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_task_0"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="2dp"
|
||||
android:layout_weight="1"
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:text="任务1" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_task_1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="2dp"
|
||||
android:layout_weight="1"
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:text="任务2" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_task_2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="2dp"
|
||||
android:layout_weight="1"
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:text="任务3" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_task_3"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="2dp"
|
||||
android:layout_weight="1"
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:text="任务4" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_task_4"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="2dp"
|
||||
android:layout_weight="1"
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:text="任务5" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_task_5"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="2dp"
|
||||
android:layout_weight="1"
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:text="任务6" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_task_6"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="2dp"
|
||||
android:layout_weight="1"
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:text="任务7" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_task_7"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="2dp"
|
||||
android:layout_weight="1"
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:text="任务8" />
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_task_8"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="2dp"
|
||||
android:layout_weight="1"
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:text="任务9" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_task_9"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="2dp"
|
||||
android:layout_weight="1"
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:text="任务10" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_task_10"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="2dp"
|
||||
android:layout_weight="1"
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:text="任务11" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_task_11"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="2dp"
|
||||
android:layout_weight="1"
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:text="任务12" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_task_12"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="2dp"
|
||||
android:layout_weight="1"
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:text="任务13" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_task_13"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="2dp"
|
||||
android:layout_weight="1"
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:text="无效" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_task_14"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="2dp"
|
||||
android:layout_weight="1"
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:text="无效" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_task_15"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="2dp"
|
||||
android:layout_weight="1"
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:text="无效" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,188 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2023. UnknownNetworkService Group
|
||||
~ This file is created by UnknownObject at 2023 - 5 - 1
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:context=".gui.SingleFunctionTest">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_camera_up"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="3dp"
|
||||
android:layout_marginRight="3dp"
|
||||
android:layout_weight="1"
|
||||
android:paddingLeft="10dp"
|
||||
android:paddingRight="10dp"
|
||||
android:text="摄像头\n向上" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_camera_down"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="3dp"
|
||||
android:layout_marginRight="3dp"
|
||||
android:layout_weight="1"
|
||||
android:paddingLeft="10dp"
|
||||
android:paddingRight="10dp"
|
||||
android:text="摄像头\n向下" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_camera_left"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="3dp"
|
||||
android:layout_marginRight="3dp"
|
||||
android:layout_weight="1"
|
||||
android:paddingLeft="10dp"
|
||||
android:paddingRight="10dp"
|
||||
android:text="摄像头\n向左" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_camera_right"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="3dp"
|
||||
android:layout_marginRight="3dp"
|
||||
android:layout_weight="1"
|
||||
android:paddingLeft="10dp"
|
||||
android:paddingRight="10dp"
|
||||
android:text="摄像头\n向右" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_start_qr"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="2dp"
|
||||
android:layout_weight="1"
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:paddingHorizontal="2dp"
|
||||
android:paddingLeft="0dp"
|
||||
android:paddingTop="0dp"
|
||||
android:paddingRight="0dp"
|
||||
android:paddingBottom="0dp"
|
||||
android:text="二维码识别" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_start_light"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="2dp"
|
||||
android:layout_weight="1"
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:paddingHorizontal="2dp"
|
||||
android:paddingLeft="0dp"
|
||||
android:paddingTop="0dp"
|
||||
android:paddingRight="0dp"
|
||||
android:paddingBottom="0dp"
|
||||
android:text="交通灯识别" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_start_color_shape"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="2dp"
|
||||
android:layout_weight="1"
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:paddingHorizontal="2dp"
|
||||
android:paddingLeft="0dp"
|
||||
android:paddingTop="0dp"
|
||||
android:paddingRight="0dp"
|
||||
android:paddingBottom="0dp"
|
||||
android:text="形状颜色识别" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_start_car_id"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="2dp"
|
||||
android:layout_weight="1"
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:paddingHorizontal="2dp"
|
||||
android:paddingLeft="0dp"
|
||||
android:paddingTop="0dp"
|
||||
android:paddingRight="0dp"
|
||||
android:paddingBottom="0dp"
|
||||
android:text="车牌识别" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_start_sign"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="2dp"
|
||||
android:layout_weight="1"
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:paddingHorizontal="2dp"
|
||||
android:paddingLeft="0dp"
|
||||
android:paddingTop="0dp"
|
||||
android:paddingRight="0dp"
|
||||
android:paddingBottom="0dp"
|
||||
android:text="交通标志识别" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_start_ocr"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="2dp"
|
||||
android:layout_weight="1"
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:paddingHorizontal="2dp"
|
||||
android:paddingLeft="0dp"
|
||||
android:paddingTop="0dp"
|
||||
android:paddingRight="0dp"
|
||||
android:paddingBottom="0dp"
|
||||
android:text="OCR" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_tft_page_down"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="3dp"
|
||||
android:text="TFT下翻一页" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_movement_control"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="3dp"
|
||||
android:layout_weight="1"
|
||||
android:text="移动控制" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_crash"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="3dp"
|
||||
android:layout_weight="1"
|
||||
android:text="立即崩溃" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
Reference in New Issue
Block a user