dev: разработан новый алгоритм детекции состояний системы в клиентских трейсах
This commit is contained in:
parent
90b6660a15
commit
9be6843307
@ -1,23 +1,29 @@
|
||||
{
|
||||
"robot_zero_velocity_trashold": [
|
||||
0.008
|
||||
"act_vel_min": [
|
||||
1800.0
|
||||
],
|
||||
"actuator_zero_velocity_trashold": [
|
||||
100.0
|
||||
"act_vel_close": [
|
||||
1700.0
|
||||
],
|
||||
"actuator_finishing_velocity": [
|
||||
2000.0
|
||||
"act_vel_thresh": [
|
||||
10.0
|
||||
],
|
||||
"actuator_finishing_velocity_trashold": [
|
||||
"act_vel_negative": [
|
||||
200.0
|
||||
],
|
||||
"actuator_current_trashold": [
|
||||
0.5
|
||||
"rob_vel_thresh": [
|
||||
4.0
|
||||
],
|
||||
"ROI_start": [
|
||||
8.0
|
||||
"act_force_close": [
|
||||
700.0
|
||||
],
|
||||
"ROI_finish": [
|
||||
43.0
|
||||
"act_force_weld": [
|
||||
1300.0
|
||||
],
|
||||
"force_increase": [
|
||||
100.0
|
||||
],
|
||||
"force_decrease": [
|
||||
100.0
|
||||
]
|
||||
}
|
||||
@ -241,13 +241,15 @@ class OperatorSettings(settingsWindow):
|
||||
class FilterSettings(settingsWindow):
|
||||
def __init__(self, path, name, upd_func):
|
||||
assosiated_names = {
|
||||
"robot_zero_velocity_trashold" : "Robot zero speed filter +-m/sec",
|
||||
"actuator_zero_velocity_trashold" : "Actuator zero speed filter +-m/sec",
|
||||
"actuator_finishing_velocity" : "Actuator finishing speed m/sec",
|
||||
"actuator_finishing_velocity_trashold" : "Actuator finishing speed filter m/sec",
|
||||
"actuator_current_trashold": "Actuator force filter N",
|
||||
"ROI_start" : "Start time, sec",
|
||||
"ROI_finish" : "End time, sec"
|
||||
"act_vel_min" : "Minimum for ME speed in Closing mm/sec",
|
||||
"act_vel_close" : "Maximum for ME speed in Squeeze mm/sec",
|
||||
"act_vel_thresh" : "ME zero speed threshold mm/sec",
|
||||
"act_vel_negative" : "ME Relief speed mm/sec",
|
||||
"rob_vel_thresh": "Robot zero speed threshold mm/sec",
|
||||
"act_force_close" : "Maximum ME force in Closing, N",
|
||||
"act_force_weld" : "Minimum ME force in Welding, N",
|
||||
"force_increase": "ME force rising speed in Squeeze",
|
||||
"force_decrease":"ME force falling speed in Relief"
|
||||
}
|
||||
super().__init__(path, name, upd_func, assosiated_names)
|
||||
self._num_points.setVisible(False)
|
||||
|
||||
@ -173,63 +173,104 @@ class TraceStageDetector(BaseTraceStageDetector):
|
||||
def __init__(self, parent:TraceProcessor = None):
|
||||
super().__init__(parent)
|
||||
|
||||
def detect_stages(self, df: pd.DataFrame) -> list:
|
||||
df = df.sort_index()
|
||||
stage_markers = []
|
||||
timestamps = df['time'].to_list() # времена (в секундах) как список
|
||||
|
||||
for i, time in enumerate(timestamps):
|
||||
mark = self._mark_timestamp(df, i, time)
|
||||
if mark: stage_markers.append(mark)
|
||||
|
||||
# Объединяем подряд идущие одинаковые метки в единые этапы.
|
||||
stages = self._merge_marks_to_stages(stage_markers, timestamps)
|
||||
return stages
|
||||
|
||||
def _mark_timestamp(self, df:pd.DataFrame, index:int, time:float) -> Union[str, None]:
|
||||
# Не интересные значения помечаем как "unknown"
|
||||
if (time < self._parent._settings.filter["ROI_start"][0] or
|
||||
time > self._parent._settings.filter["ROI_finish"][0]):
|
||||
return "unknown"
|
||||
|
||||
rob_vel = df.loc[index, "CartVel_Act"]
|
||||
act_vel = df.loc[index, "DriveMotorVel_Act7"]
|
||||
act_curr = df.loc[index, "DriveMotorCurr_Act7"]
|
||||
@staticmethod
|
||||
def is_closing(rob_vel:float,
|
||||
act_vel:float,
|
||||
act_force:float,
|
||||
th:dict) -> bool:
|
||||
# act_vel > min, rob_vel ~ 0, act_force ниже порога
|
||||
return act_vel > th['act_vel_min'] and abs(rob_vel) < th['rob_vel_thresh'] and act_force < th['act_force_close']
|
||||
|
||||
if abs(rob_vel) > self._parent._settings.filter["robot_zero_velocity_trashold"][0]:
|
||||
return "Oncomming"
|
||||
@staticmethod
|
||||
def is_squeeze(rob_vel:float,
|
||||
act_vel:float,
|
||||
act_force:float,
|
||||
force_rate:float,
|
||||
th:dict) -> bool:
|
||||
# rob_vel ~ 0, act_vel меньше, чем в closing, и резкий рост act_force
|
||||
return abs(rob_vel) < th['rob_vel_thresh'] and act_vel < th['act_vel_close'] and force_rate > th['force_increase']
|
||||
|
||||
if (abs(act_vel) < self._parent._settings.filter["actuator_zero_velocity_trashold"][0] and
|
||||
abs(act_curr) > self._parent._settings.filter["actuator_current_trashold"][0]):
|
||||
return "Squeeze&Welding&Relief"
|
||||
@staticmethod
|
||||
def is_welding(rob_vel:float,
|
||||
act_vel:float,
|
||||
act_force:float,
|
||||
th:dict) -> bool:
|
||||
# обе скорости ≈ 0, act_force выше порога сварки
|
||||
return abs(rob_vel) < th['rob_vel_thresh'] and abs(act_vel) < th['act_vel_thresh'] and act_force > th['act_force_weld']
|
||||
|
||||
if self._parent._settings.filter["actuator_finishing_velocity_trashold"][0] > abs(abs(act_vel) - self._parent._settings.filter["actuator_finishing_velocity"][0]):
|
||||
return "Closing"
|
||||
@staticmethod
|
||||
def is_relief(rob_vel:float,
|
||||
act_vel:float,
|
||||
act_force:float,
|
||||
force_rate:float,
|
||||
th:dict) -> bool:
|
||||
# резкое падение act_force, отрицательный act_vel, малые rob_vel
|
||||
return force_rate < -th['force_decrease'] and act_vel < -th['act_vel_negative'] and abs(rob_vel) < th['rob_vel_thresh']
|
||||
|
||||
def detect_stages(self, df:pd.DataFrame):
|
||||
timestamps = df['time'].to_list()
|
||||
n = len(df)
|
||||
th = {key: item[0] for key, item in self._parent._settings.filter.items()}
|
||||
# Вычисляем разностную производную силы
|
||||
act_force = df["DriveMotorTorq_Act7"].values
|
||||
force_diff = np.diff(act_force, prepend=act_force[0])
|
||||
|
||||
return None
|
||||
|
||||
def _merge_marks_to_stages(self, stage_markers:list, timestamps:list) -> list:
|
||||
stages = []
|
||||
current_stage = stage_markers[0]
|
||||
start_time = timestamps[0]
|
||||
|
||||
for i in range(1, len(stage_markers)):
|
||||
if stage_markers[i] != current_stage:
|
||||
end_time = timestamps[i - 1]
|
||||
stages.append({
|
||||
"stage": current_stage,
|
||||
"start_time": start_time,
|
||||
"end_time": end_time
|
||||
})
|
||||
current_stage = stage_markers[i]
|
||||
start_time = timestamps[i]
|
||||
|
||||
stages.append({
|
||||
"stage": current_stage,
|
||||
"start_time": start_time,
|
||||
"end_time": timestamps[-1]
|
||||
})
|
||||
return stages
|
||||
states = []
|
||||
current_state = "Oncomming"
|
||||
state_start = timestamps[0]
|
||||
|
||||
# Проходим по всем записям
|
||||
for i in range(n):
|
||||
rob_vel = df.loc[i, "CartVel_Act"]
|
||||
act_vel = df.loc[i, "DriveMotorVel_Act7"]
|
||||
act_force_val = df.loc[i, "DriveMotorTorq_Act7"]
|
||||
force_rate = force_diff[i]
|
||||
|
||||
if current_state == "Oncomming":
|
||||
if self.is_closing(rob_vel, act_vel, act_force_val, th):
|
||||
state_end = timestamps[i]
|
||||
states.append(("Oncomming", state_start, state_end))
|
||||
current_state = "Closing"
|
||||
state_start = timestamps[i]
|
||||
|
||||
elif current_state == "Closing":
|
||||
if self.is_squeeze(rob_vel, act_vel, act_force_val, force_rate, th):
|
||||
state_end = timestamps[i]
|
||||
states.append(("Closing", state_start, state_end))
|
||||
current_state = "Squeeze"
|
||||
state_start = timestamps[i]
|
||||
|
||||
elif current_state == "Squeeze":
|
||||
if self.is_welding(rob_vel, act_vel, act_force_val, th):
|
||||
state_end = timestamps[i]
|
||||
states.append(("Squeeze", state_start, state_end))
|
||||
current_state = "Welding"
|
||||
state_start = timestamps[i]
|
||||
|
||||
elif current_state == "Welding":
|
||||
if self.is_relief(rob_vel, act_vel, act_force_val, force_rate, th):
|
||||
state_end = timestamps[i]
|
||||
states.append(("Welding", state_start, state_end))
|
||||
current_state = "Relief"
|
||||
state_start = timestamps[i]
|
||||
|
||||
elif current_state == "Relief":
|
||||
# Когда признаки relief отпадают, считаем, что цикл завершён и возвращаемся в Oncomming
|
||||
if not self.is_relief(rob_vel, act_vel, act_force_val, force_rate, th):
|
||||
state_end = timestamps[i]
|
||||
states.append(("Relief", state_start, state_end))
|
||||
current_state = "Oncomming"
|
||||
state_start = timestamps[i]
|
||||
|
||||
# Фиксируем последний сегмент
|
||||
states.append((current_state, state_start, timestamps[-1]))
|
||||
return states
|
||||
|
||||
|
||||
class TextStageDetector(BaseTextStageDetector):
|
||||
@ -305,8 +346,9 @@ class TraceProcessor(BaseRawTraceProcessor):
|
||||
def _detect_stages(self, trace_df:pd.DataFrame, text_data:list) -> dict[list]:
|
||||
if trace_df is not None and text_data is not None:
|
||||
trace_stages = self._data_detector.detect_stages(trace_df)
|
||||
welding_stages = self._text_detector.detect_welding(text_data)
|
||||
events = self._form_events(trace_stages, welding_stages)
|
||||
#welding_stages = self._text_detector.detect_welding(text_data)
|
||||
#events = self._form_events(trace_stages, welding_stages)
|
||||
events = self.__form_events_2(trace_stages)
|
||||
return events
|
||||
return None
|
||||
|
||||
@ -354,6 +396,21 @@ class TraceProcessor(BaseRawTraceProcessor):
|
||||
events[trace_stages[i]['stage']][1].append(trace_stages[i]['end_time'])
|
||||
normalized_events = TraceProcessor._normalize_events(events)
|
||||
return normalized_events
|
||||
|
||||
@staticmethod
|
||||
def __form_events_2(trace_stages:list):
|
||||
events = {
|
||||
"Closing":[[],[]],
|
||||
"Squeeze":[[],[]],
|
||||
"Welding":[[],[]],
|
||||
"Relief":[[],[]],
|
||||
"Oncomming":[[],[]]
|
||||
}
|
||||
for stage in trace_stages:
|
||||
name, start_t, end_t = stage
|
||||
events[name][0].append(start_t)
|
||||
events[name][1].append(end_t)
|
||||
return events
|
||||
|
||||
@staticmethod
|
||||
def _rename_df_columns(dataframe: pd.DataFrame) -> pd.DataFrame:
|
||||
|
||||
@ -86,7 +86,7 @@ DIAEXTENDED
|
||||
#BEGINCHANNELHEADER
|
||||
200,DriveMotorPos_Act7
|
||||
201,AxisValAtMMInterface
|
||||
202,°
|
||||
202,<EFBFBD>
|
||||
210,EXPLIZIT
|
||||
211,teslaSP_VelTCP_KRCIpo.r64
|
||||
213,BLOCK
|
||||
@ -101,7 +101,7 @@ DIAEXTENDED
|
||||
#BEGINCHANNELHEADER
|
||||
200,DriveMotorVel_Act7
|
||||
201,AxisValAtMMInterface
|
||||
202,°/s
|
||||
202,<EFBFBD>/s
|
||||
210,EXPLIZIT
|
||||
211,teslaSP_VelTCP_KRCIpo.r64
|
||||
213,BLOCK
|
||||
@ -124,7 +124,7 @@ DIAEXTENDED
|
||||
220,3806
|
||||
221,7
|
||||
240,0
|
||||
241,1.000000e+00
|
||||
241,1.000000e+03
|
||||
#ENDCHANNELHEADER
|
||||
|
||||
|
||||
@ -169,7 +169,7 @@ DIAEXTENDED
|
||||
220,3806
|
||||
221,10
|
||||
240,0
|
||||
241,1.000000e-03
|
||||
241,1.000000e+00
|
||||
#ENDCHANNELHEADER
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user