Browse Source

算法更新

develop
白凤吉 2 months ago
parent
commit
a25e3893d1
  1. 4
      app/build.gradle
  2. 6
      app/src/main/java/com/iflytop/profilometer/api/measure/MeasureApi.java
  3. 3
      app/src/main/java/com/iflytop/profilometer/core/db/helper/MyDatabaseHelper.java
  4. 22
      app/src/main/java/com/iflytop/profilometer/core/migration/algo/ProfilometerPulleyPointPreProcesser.java
  5. 64
      app/src/main/java/com/iflytop/profilometer/core/migration/algo/ProfilometerRecorder.java
  6. 4
      app/src/main/java/com/iflytop/profilometer/core/migration/algo/type/ProfilometerAlgoConfig.java
  7. 23
      app/src/main/java/com/iflytop/profilometer/core/migration/algo/type/RailProfileMeasureTaskStatus.java
  8. 2
      app/src/main/java/com/iflytop/profilometer/core/migration/algo/type/Version.java
  9. 56
      app/src/main/java/com/iflytop/profilometer/dao/ProfileRecordDao.java
  10. 9
      app/src/main/java/com/iflytop/profilometer/model/entity/ProfileRecordDescription.java

4
app/build.gradle

@ -14,9 +14,9 @@ android {
minSdk 26
targetSdk 35
//
versionCode 20
versionCode 22
//
versionName "1.1.20"
versionName "1.1.22"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

6
app/src/main/java/com/iflytop/profilometer/api/measure/MeasureApi.java

@ -81,8 +81,14 @@ public class MeasureApi {
public String save(JSONObject params) {
ProfileRecordDao profileRecordDao = new ProfileRecordDao(context);
ProfileRecordPointSetDao profileRecordPointSetDao = new ProfileRecordPointSetDao(context);
ProfileRecordDescription previous = profileRecordDao.getTodayFirstProfileRecord();
int number = 1;
if(previous != null){
number = previous.getTodayNumber() + 1;
}
ProfileRecordDescription profileRecordDescription = new ProfileRecordDescription();
profileRecordDescription.setUuid(UUID.randomUUID().toString());
profileRecordDescription.setTodayNumber(number);
profileRecordDescription.setOperator(params.getStr("operator"));
profileRecordDescription.setName(params.getStr("name"));
profileRecordDescription.setTljCode(params.getStr("tljCode"));

3
app/src/main/java/com/iflytop/profilometer/core/db/helper/MyDatabaseHelper.java

@ -7,7 +7,7 @@ import android.database.sqlite.SQLiteOpenHelper;
public class MyDatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "app.db";
private static final int DATABASE_VERSION = 13; // 升级版本号
private static final int DATABASE_VERSION = 14; // 升级版本号
// 表名
public static final String TABLE_APP_USER = "app_user";
@ -39,6 +39,7 @@ public class MyDatabaseHelper extends SQLiteOpenHelper {
+ "create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, "
+ "update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, "
+ "uuid TEXT, "
+ "today_number INTEGER, "
+ "operator TEXT, "
+ "tlj_code TEXT, "
+ "gwd_code TEXT, "

22
app/src/main/java/com/iflytop/profilometer/core/migration/algo/ProfilometerPulleyPointPreProcesser.java

@ -64,12 +64,24 @@ public class ProfilometerPulleyPointPreProcesser {
List<XYPoint> outline1;
List<XYPoint> outline2;
outline1 = filterCrossingBoundaryPoint(pulleyLine1, line1side);
double filterThreshold = 0;
if (line1side.equals(MeasureSide.LEFT)) {
if (!pulleyLine1.isEmpty() && pulleyLine1.get(0).x < 0) {
filterThreshold = pulleyLine1.get(0).x;
}
} else {
if (!pulleyLine1.isEmpty() && pulleyLine1.get(0).x > 0) {
filterThreshold = pulleyLine1.get(0).x;
}
}
outline1 = filterCrossingBoundaryPoint(pulleyLine1, line1side, filterThreshold);
outline1 = processPulleyPoint(config, profile, outline1, line1side);
outline1 = filterTheClosedPoint(config, outline1, line1side);
outline1 = filterTheTails(config, outline1, line2side);
outline2 = filterCrossingBoundaryPoint(pulleyLine2, line2side);
outline2 = filterCrossingBoundaryPoint(pulleyLine2, line2side, filterThreshold);
outline2 = processPulleyPoint(config, profile, outline2, line2side);
outline2 = filterTheClosedPoint(config, outline2, line2side);
outline2 = filterTheTails(config, outline2, line2side);
@ -117,7 +129,7 @@ public class ProfilometerPulleyPointPreProcesser {
return retoutline;
}
static private List<XYPoint> filterCrossingBoundaryPoint(List<XYPoint> outlinePoint, MeasureSide pointSide) {
static private List<XYPoint> filterCrossingBoundaryPoint(List<XYPoint> outlinePoint, MeasureSide pointSide, double filterThreshold) {
/*
* 左侧只保留x<0的点
* 右侧只保留x>0的点
@ -125,13 +137,13 @@ public class ProfilometerPulleyPointPreProcesser {
List<XYPoint> retOutlinePoint = new ArrayList<>();
if (pointSide.equals(MeasureSide.LEFT)) {
for (XYPoint point : outlinePoint) {
if (point.x <= 0) {
if (point.x <= filterThreshold) {
retOutlinePoint.add(point);
}
}
} else if (pointSide.equals(MeasureSide.RIGHT)) {
for (XYPoint point : outlinePoint) {
if (point.x >= 0) {
if (point.x >= filterThreshold) {
retOutlinePoint.add(point);
}
}

64
app/src/main/java/com/iflytop/profilometer/core/migration/algo/ProfilometerRecorder.java

@ -15,13 +15,11 @@ import java.util.List;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class ProfilometerRecorder {
//
// 状态
//
List<XYPoint> dataCache1; //曲线缓存
List<XYPoint> dataCache2; //曲线缓存
@ -30,6 +28,7 @@ public class ProfilometerRecorder {
MeasureSide firstSide = MeasureSide.LEFT; //第一条曲线的测量方向
double firstSideXVal = 0;
Boolean rightSideReady = false; //左侧测量完成
Boolean leftSideReady = false; //右侧测量完成
@ -50,7 +49,6 @@ public class ProfilometerRecorder {
ProfilometerAlgoConfig cfg = new ProfilometerAlgoConfig();
DeviceProfile deviceProfile;
synchronized public void initialize(ProfilometerAlgoConfig config, ProfilometerDrawerListener listener) {
this.listener = listener;
if (config == null) {
@ -66,6 +64,7 @@ public class ProfilometerRecorder {
dataCache1 = new ArrayList<>();
dataCache2 = new ArrayList<>();
firstSide = null;
firstSideXVal = 0;
rightSideReady = false;
lastDisplayPoint = null;
leftSideReady = false;
@ -78,6 +77,14 @@ public class ProfilometerRecorder {
resetContext();
}
synchronized void loginfo(String fmt, Object... args) {
}
synchronized void logdebug(String fmt, Object... args) {
}
synchronized public void processRawEncoderData(Integer sensor1data, Integer sensor2data) {
sensor1data = sensor1data & 0xFFFFF000;
@ -94,7 +101,7 @@ public class ProfilometerRecorder {
if (status == RailProfileMeasureTaskStatus.START_MEASURE) {
status = RailProfileMeasureTaskStatus.WAITING_FOR_RECORD_THE_1ST_SIDE;
log.info("等待记录第一条曲线");
loginfo("等待记录第一条曲线");
if (listener != null)
listener.onWaitingForMeasuringThe1stSide();
} else if (status == RailProfileMeasureTaskStatus.WAITING_FOR_RECORD_THE_1ST_SIDE) {
@ -105,7 +112,7 @@ public class ProfilometerRecorder {
processDataOnRecordTheFirstSide(arm1rad, arm2rad, newPoitn);
} else if (status == RailProfileMeasureTaskStatus.RECORD_THE_1ST_SIDE_FINISHED) {
status = RailProfileMeasureTaskStatus.WAITING_FOR_RECORD_THE_2ND_SIDE;
log.info("等待记录第二条曲线 {}", firstSide.getOpposite());
loginfo("等待记录第二条曲线 {}", firstSide.getOpposite());
if (listener != null)
listener.waitingForMeasuringThe2NdSide(firstSide.getOpposite());
} else if (status == RailProfileMeasureTaskStatus.WAITING_FOR_RECORD_THE_2ND_SIDE) {
@ -238,14 +245,16 @@ public class ProfilometerRecorder {
MeasureSide nowside = rad1 < 0 ? MeasureSide.LEFT : MeasureSide.RIGHT;
if (nowside.equals(MeasureSide.RIGHT)) {
isInStartPos = newPoint.x <= 0 && newPoint.x >= -hight / 2.0
&& newPoint.y <= weight / 2.0 && newPoint.y >= -weight / 2.0;
} else {
isInStartPos = newPoint.x <= hight / 2.0 && newPoint.x >= 0
&& newPoint.y <= weight / 2.0 && newPoint.y >= -weight / 2.0;
}
// if (nowside.equals(MeasureSide.RIGHT)) {
// isInStartPos = newPoint.x <= 0 && newPoint.x >= -hight / 2.0
// && newPoint.y <= weight / 2.0 && newPoint.y >= -weight / 2.0;
// } else {
// isInStartPos = newPoint.x <= hight / 2.0 && newPoint.x >= 0
// && newPoint.y <= weight / 2.0 && newPoint.y >= -weight / 2.0;
// }
isInStartPos = newPoint.x <= hight / 2.0 && newPoint.x >= -hight / 2.0
&& newPoint.y <= weight / 2.0 && newPoint.y >= -weight / 2.0;
if (stillRefPoint == null) {
stillRefPoint = newPoint;
@ -253,7 +262,7 @@ public class ProfilometerRecorder {
boolean still = (distance(stillRefPoint, newPoint)) < cfg.stillJudgeThreshold;
lastpoint = newPoint;
// log.info("still: {}, isInStartPos: {}, newPoint: {}, lastpoint: {}", still, isInStartPos, newPoint, lastpoint);
logdebug("still: {}, isInStartPos: {}, newPoint: {}, lastpoint: {}", still, isInStartPos, newPoint, lastpoint);
if (!stillFlag) {
if (still) {
@ -272,7 +281,20 @@ public class ProfilometerRecorder {
//开始测量第一条曲线
status = RailProfileMeasureTaskStatus.RECORD_THE_FIRST_SIDE;
firstSide = rad1 < 0 ? MeasureSide.LEFT : MeasureSide.RIGHT;
log.info("开始测量第一条曲线 {}", firstSide);
if (firstSide.equals(MeasureSide.LEFT)) {
if (newPoint.x < 0) {
firstSideXVal = newPoint.x;
} else {
firstSideXVal = 0;
}
} else {
if (newPoint.x > 0) {
firstSideXVal = newPoint.x;
} else {
firstSideXVal = 0;
}
}
loginfo("开始测量第一条曲线 {} at", firstSide, firstSideXVal);
if (listener != null)
listener.onStartRecordThe1stSide(firstSide);
@ -294,13 +316,9 @@ public class ProfilometerRecorder {
XYPoint lp0 = directionJudgeCache.get(directionJudgeCache.size() - 1);
XYPoint lp1 = directionJudgeCache.get(directionJudgeCache.size() - 2);
XYPoint lp2 = directionJudgeCache.get(directionJudgeCache.size() - 3);
double ddirec = calculateAngle(lp0, lp1, lp2);
// XYPoint runDirection1 = new XYPoint(lp0.x - lp1.x, lp0.y - lp1.y);
// XYPoint runDirection2 = new XYPoint(lp1.x - lp2.x, lp1.y - lp2.y);
// double ddirec = runDirection1.x * runDirection2.x + runDirection1.y * runDirection2.y;
log.debug("ddirec: {}, speedNow: {}", ddirec, speedNow);
logdebug("ddirec: {}, speedNow: {}", ddirec, speedNow);
if (ddirec > 60) {
endFlag = true;
}
@ -352,7 +370,7 @@ public class ProfilometerRecorder {
boolean endFlag = isEnd(rad1, rad2, newPoint);
if (endFlag) {
//测量完成
log.info("测量完成,第一条曲线 {}", firstSide);
loginfo("测量完成,第一条曲线 {}", firstSide);
status = RailProfileMeasureTaskStatus.RECORD_THE_1ST_SIDE_FINISHED;
resetContext();
if (firstSide == MeasureSide.LEFT) {
@ -379,10 +397,10 @@ public class ProfilometerRecorder {
*
*/
if ((leftSideReady && newPoint.x >= 0) || rightSideReady && newPoint.x <= 0) {
if ((leftSideReady && newPoint.x >= firstSideXVal) || rightSideReady && newPoint.x <= firstSideXVal) {
//开始测量第二条曲线
status = RailProfileMeasureTaskStatus.RECORD_THE_2ND_SIDE;
log.info("开始测量第二条曲线 {}", firstSide.getOpposite());
loginfo("开始测量第二条曲线 {}", firstSide.getOpposite());
if (listener != null)
listener.onStartRecordThe2NdSide(firstSide.getOpposite());
dataCache2.add(newPoint);
@ -425,7 +443,7 @@ public class ProfilometerRecorder {
boolean endFlag = isEnd(rad1, rad2, newPoint);
if (endFlag) {
//测量完成
log.info("测量完成,第二条曲线 {}", firstSide.getOpposite());
loginfo("测量完成,第二条曲线 {}", firstSide.getOpposite());
status = RailProfileMeasureTaskStatus.FINISHED;
if (listener != null)
listener.onFinished(firstSide.getOpposite());

4
app/src/main/java/com/iflytop/profilometer/core/migration/algo/type/ProfilometerAlgoConfig.java

@ -3,11 +3,11 @@ package com.iflytop.profilometer.core.migration.algo.type;
public class ProfilometerAlgoConfig {
public int outlineStartRecordSigJudgeTimeThresholdMS = 400; // 开始采样静止时间判定阈值单位MS
public int startOutlineRecordingTimingJudgmentAreaHight = 30; // 开始采样静止时间判定区域高度单位mm
public int startOutlineRecordingTimingJudgmentAreaWeight = 95; // 开始采样静止时间判定区域权重单位mm
public int startOutlineRecordingTimingJudgmentAreaWeight = 90; // 开始采样静止时间判定区域权重单位mm
public double precision = 0.10; // 采样精度(mm) 当其等于0.12mm,满足测量长度13cm的情况下1500个点.
public double overSamplePrecision = 0.03; // 过采样精度(mm) 0.03mm
public double displayPrecision = 0.3; // 显示精度(影响采样时候的回调的次数)
public double stillJudgeThreshold = 4; // 静止判断阈值(mm),当前点与上一个点的距离小于该值认为静止
public double stillJudgeThreshold = 0.5; // 静止判断阈值(mm),当前点与上一个点的距离小于该值认为静止
public double outlineComputeRefPointDistance = 0.2; // (mm) 计算轮廓线时两个参考点距离
public double directionJudgePointDistance = 1;// (mm) 方向判断点距离,该值越大方向判定越准确结束条件判定也就更准确但是错误的采样点数也会增加

23
app/src/main/java/com/iflytop/profilometer/core/migration/algo/type/RailProfileMeasureTaskStatus.java

@ -35,27 +35,4 @@ public enum RailProfileMeasureTaskStatus {
FINISHED,
;
public String toCHString() {
switch (this) {
case IDLE:
return "空闲";
case START_MEASURE:
return "开始测量";
case WAITING_FOR_RECORD_THE_1ST_SIDE:
return "等待测量第一条曲线";
case RECORD_THE_FIRST_SIDE:
return "测量第一条曲线";
case RECORD_THE_1ST_SIDE_FINISHED:
return "第一条曲线测量完成";
case WAITING_FOR_RECORD_THE_2ND_SIDE:
return "等待测量第二条曲线";
case RECORD_THE_2ND_SIDE:
return "测量第二条曲线";
case FINISHED:
return "测量完成";
default:
throw new IllegalStateException("Unexpected state: " + this);
}
}
}

2
app/src/main/java/com/iflytop/profilometer/core/migration/algo/type/Version.java

@ -1,7 +1,7 @@
package com.iflytop.profilometer.core.migration.algo.type;
public class Version {
static public final Integer VERSION_MAIN = 23;
static public final Integer VERSION_MAIN = 26;
static public String getVersion() {
return String.format("V%d", VERSION_MAIN);

56
app/src/main/java/com/iflytop/profilometer/dao/ProfileRecordDao.java

@ -36,6 +36,7 @@ public class ProfileRecordDao {
values.put("create_time", currentTime);
values.put("update_time", currentTime);
values.put("uuid", record.getUuid());
values.put("today_number", record.getTodayNumber());
values.put("operator", record.getOperator());
values.put("name", record.getName());
values.put("tlj_code", record.getTljCode());
@ -66,6 +67,7 @@ public class ProfileRecordDao {
ContentValues values = new ContentValues();
values.put("update_time", getCurrentTime());
values.put("uuid", record.getUuid());
values.put("today_number", record.getTodayNumber());
values.put("operator", record.getOperator());
values.put("name", record.getName());
values.put("tlj_code", record.getTljCode());
@ -109,6 +111,7 @@ public class ProfileRecordDao {
ProfileRecordDescription record = new ProfileRecordDescription();
record.setId(cursor.getLong(cursor.getColumnIndex("id")));
record.setUuid(cursor.getString(cursor.getColumnIndex("uuid")));
record.setTodayNumber(cursor.getInt(cursor.getColumnIndex("today_number")));
record.setOperator(cursor.getString(cursor.getColumnIndex("operator")));
record.setName(cursor.getString(cursor.getColumnIndex("name")));
record.setTljCode(cursor.getString(cursor.getColumnIndex("tlj_code")));
@ -164,6 +167,7 @@ public class ProfileRecordDao {
record = new ProfileRecordDescription();
record.setId(cursor.getLong(cursor.getColumnIndex("id")));
record.setUuid(cursor.getString(cursor.getColumnIndex("uuid")));
record.setTodayNumber(cursor.getInt(cursor.getColumnIndex("today_number")));
record.setOperator(cursor.getString(cursor.getColumnIndex("operator")));
record.setName(cursor.getString(cursor.getColumnIndex("name")));
record.setTljCode(cursor.getString(cursor.getColumnIndex("tlj_code")));
@ -229,6 +233,7 @@ public class ProfileRecordDao {
ProfileRecordDescription record = new ProfileRecordDescription();
record.setId(cursor.getLong(cursor.getColumnIndex("id")));
record.setUuid(cursor.getString(cursor.getColumnIndex("uuid")));
record.setTodayNumber(cursor.getInt(cursor.getColumnIndex("today_number")));
record.setOperator(cursor.getString(cursor.getColumnIndex("operator")));
record.setName(cursor.getString(cursor.getColumnIndex("name")));
record.setTljCode(cursor.getString(cursor.getColumnIndex("tlj_code")));
@ -266,6 +271,57 @@ public class ProfileRecordDao {
return resultList;
}
// 查询今天的数据并按照 today_number 字段倒序排列获取第一条数据
@SuppressLint("Range")
public ProfileRecordDescription getTodayFirstProfileRecord() {
ProfileRecordDescription record = null;
SQLiteDatabase db = dbHelper.getReadableDatabase();
// 获取今天的日期
String today = LocalDateTime.now().format(DAY_FORMATTER);
// 查询今天的数据按照 today_number 字段倒序排列并获取第一条数据
String sql = "SELECT * FROM " + MyDatabaseHelper.TABLE_PROFILE_RECORD +
" WHERE strftime('%Y-%m-%d', create_time) = ? " +
"ORDER BY today_number DESC LIMIT 1";
Cursor cursor = db.rawQuery(sql, new String[]{today});
if (cursor.moveToFirst()) {
record = new ProfileRecordDescription();
record.setId(cursor.getLong(cursor.getColumnIndex("id")));
record.setUuid(cursor.getString(cursor.getColumnIndex("uuid")));
record.setTodayNumber(cursor.getInt(cursor.getColumnIndex("today_number")));
record.setOperator(cursor.getString(cursor.getColumnIndex("operator")));
record.setName(cursor.getString(cursor.getColumnIndex("name")));
record.setTljCode(cursor.getString(cursor.getColumnIndex("tlj_code")));
record.setGwdCode(cursor.getString(cursor.getColumnIndex("gwd_code")));
record.setXmCode(cursor.getString(cursor.getColumnIndex("xm_code")));
record.setStationCode(cursor.getString(cursor.getColumnIndex("station_code")));
record.setDataType(cursor.getString(cursor.getColumnIndex("data_type")));
record.setDataSource(cursor.getString(cursor.getColumnIndex("data_source")));
record.setRailSize(cursor.getString(cursor.getColumnIndex("rail_size")));
record.setLineClassify(cursor.getString(cursor.getColumnIndex("line_classify")));
record.setBatch(cursor.getString(cursor.getColumnIndex("batch")));
record.setXbCode(cursor.getString(cursor.getColumnIndex("xb_code")));
record.setMileage(cursor.getString(cursor.getColumnIndex("mileage")));
record.setUnitType(cursor.getString(cursor.getColumnIndex("unit_type")));
record.setExtraDesc(cursor.getString(cursor.getColumnIndex("extra_desc")));
record.setTurnoutNum(cursor.getString(cursor.getColumnIndex("turnout_num")));
record.setSleeperNum(cursor.getString(cursor.getColumnIndex("sleeper_num")));
record.setRadius(cursor.getString(cursor.getColumnIndex("radius")));
record.setCreateTime(LocalDateTime.parse(cursor.getString(cursor.getColumnIndex("create_time")), FORMATTER));
record.setUpdateTime(LocalDateTime.parse(cursor.getString(cursor.getColumnIndex("update_time")), FORMATTER));
String syncStatus = cursor.getString(cursor.getColumnIndex("sync_status"));
if (syncStatus != null) {
record.setSyncStatus(SyncStatus.valueOf(syncStatus));
}
}
cursor.close();
db.close();
return record;
}
private String getCurrentTime() {
return LocalDateTime.now().format(FORMATTER);
}

9
app/src/main/java/com/iflytop/profilometer/model/entity/ProfileRecordDescription.java

@ -5,6 +5,7 @@ import com.iflytop.profilometer.common.enums.SyncStatus;
public class ProfileRecordDescription extends BaseEntity {
private String uuid;
private Integer todayNumber;
private String operator;
private String name;
private String tljCode;
@ -33,6 +34,14 @@ public class ProfileRecordDescription extends BaseEntity {
this.uuid = uuid;
}
public Integer getTodayNumber() {
return todayNumber;
}
public void setTodayNumber(Integer todayNumber) {
this.todayNumber = todayNumber;
}
public String getOperator() {
return operator;
}

Loading…
Cancel
Save