simulation
판넬로 사용자 입력 받는 법
hsl7
2024. 11. 3. 10:55
시작하기 전에
판넬로 출력하는 방법 - 관계도 :: hsl's tsmaster 사용기 에서 판넬로 미니프로그램에서 계산할 결과를 출력하는 방법을 설명했다. 이번에는 판넬에서 사용자 입력을 받아 미니프로그램에 반영하는 방법을 설명한다.
개요
- CAN 신호를 실시간으로 필터링 하기 - 미니프로그램과 ai :: hsl's tsmaster 사용기 에서 설명한 칼만 필터를 이용하여 설명한다.
- 이번 설명에서는 칼만 필터의 process_noise와 measurement_noise 파라미터를 사용자가 변경할 수 있도록 한다.
- 판넬 기능을 이용하여 사용자가 파라미터를 입력할 수 있는 GUI를 만든다.
- 판넬의 입력을 미니프로그램에서 사용하려면 시스템 변수를 통해야 한다.
- 시스템 변수를 만든다.
- 판넬의 위젯을 시스템 변수와 연결한다.
- 미니프로그램에서 app.get_system_var_value() 함수들을 이용하여 시스템 변수를 읽어 연산에 사용한다.
시스템 변수 만들기
- 메인 메뉴/ Simulation/ System Variables를 클릭하여 System Variable Management 창을 엽니다.
- process_noise와 measurment_noise라는 변수를 만든다. (측정을 한 후여서 Current Value 칸에 수치가 입력되어 있다.)
GUI 만들기
- 메인 메뉴/ Simulation/ Panel/ Add Panel (혹은 기존 판넬)을 클릭하여 판넬 창을 연다.
- 프라퍼티 탭에서 아래 설정들을 변경한다.
- VarType을 SystemVar로 선택한다.
- VarLink를 선택하고, 오른쪽 3점 버튼을 클릭하면 시스템 변수 창이 열린다. 위젯과 연결할 시스템 변수를 선택한다.
- Max, Min을 이용하여 트랙바가 표시할 최대 최소값을 설정한다. Frequency에 입력할 값의 변경 단위 (해상도)를 입력한다. 아래 그림은 시스템 변수 process_noise 를 설정한 예다. 마우스를 드래그하여 0에서 1 사이에서 0.05 스텝으로 값을 입력할 수 있다.
- 트랙바로 입력한 값을 수치로 보기위해 Input Output Box를 추가한다.
- Input Output Box에 시스템 변수를 연결하는 방법은 트랙바와 같다.
미니프로그램에서 시스템 변수 읽기
- CAN 신호를 실시간으로 필터링 하기 - 미니프로그램과 ai :: hsl's tsmaster 사용기의 코드에 필터 파라미터를 업데이트 하는 코드를 추가한다.
- 수정된 부분은 아래와 같다.
# 판넬의 위젯에 연결된 시스템 변수를 읽음
process_noise = app.get_system_var_value("calc.process_noise")[1]
measurement_noise = app.get_system_var_value("calc.measurement_noise")[1]
# 필터 파리미터들을 업데이트함
kalman_filter.update_filter_parameters(process_noise, measurement_noise)
- app.get_system_var_value("calc.process_noise")를 호출하면 process_noise 시스템 변수를 리스트 형태 ([0, process_noise])로 반환한다. 값이 필요하여 [1] 인덱스를 붙였다.
- 수정된 calc_yaw_rate_ws_filt() 함수는 아래와 같다.
- 프리뷰: 나는 다음 블로그에 ai에게 조향각, 뒷바퀴 속도, 횡가속도, 종가속도를 입력하면 요-레이트(yaw_rate_model)를 계산하는 모델을 만들어 달라 요청하고, 만들어진 모델로 실시간으로 yaw_rate_model 를 계산하고, 실시간으로 yaw_rate_model 과 측정한 요-레이트를 비교하는 방법을 설명할 계획이다. 아래 코드는 다음에 설명할 프로그램에서 가져왔다. 그래서 아래 코드의 함수 이름이 cacl_yaw_rate_ws_filt_model()이다.
## functions
def calc_yaw_rate_ws_filt_model(ACAN: RawCAN) -> None:
'''
WHL_SPD11 메시지의 신호들을 이용하여 yaw_rate_ws를 계산함
yaw_rate_ws를 칼만 필터로 필터링함
yaw_rate_model을 계산함
'''
global kalman_filter
global model_yaw_rate
## yaw_rate_ws 계산
# 메시지의 바이트 데이터들을 신호들로 분리하기 위함
WHL_SPD11_1.FRawCAN = ACAN
# yaw_rate_ws를 계산한다.
whl_spd_rr_minus_rl = WHL_SPD11_1.WHL_SPD_RR - WHL_SPD11_1.WHL_SPD_RL
# 베뉴의 rear track은1.555m이다.
# wheel_spd_rr_minus_rl를 rear track으로 나눠서 yaw rate를 구한다.
# wheel speed는 kph이다. mps로 변환하기위해 1000 / 36000을 곱한다.
# radian을 deg로 변환하기 위해 180 / pi를 곱한다.
# 위 연산을 하는 것은 whl_spd_rr_minus_rl에 10.27을 곱하는 것과 같다.
yaw_rate_ws = whl_spd_rr_minus_rl * 10.27
## yaw_rate_ws를 필터링하여 yaw_rate_ws_filt를 계산
# 필터 파라미터 업데이트
# 사용자가 필터 파라미터들을 변경했을 수 있다.
# 파라미터 변경 여부를 확인하고, 변경된 경우만 업데이트하려고 했는데
# 무조건 업데이트 하는 것이 더 빠를 것 같다.
##--------------------------------
'''
칼만 필터의 파라미터를 업데이트 한다.
판넬의 위젯에 연결된 시스템 변수를 읽음
'''
process_noise = app.get_system_var_value("calc.process_noise")[1]
measurement_noise = app.get_system_var_value("calc.measurement_noise")[1]
'''
필터 파리미터들을 업데이트함
'''
kalman_filter.update_filter_parameters(process_noise, measurement_noise)
##--------------------------------
# yaw_rate_ws를 필터하여yaw_rate_ws_filt를 계산
yaw_rate_ws_filt = kalman_filter.update(yaw_rate_ws)
## yaw_rate_model 계산
# 모델 입력을 데이터프레임으로 만듬
df_input = pd.DataFrame(
{
'sas': [SAS11_1.SAS_Angle],
'ws_rl': [WHL_SPD11_1.WHL_SPD_RL],
'ws_rr': [WHL_SPD11_1.WHL_SPD_RR],
'lat_accel': [ESP12_1.LAT_ACCEL],
'long_accel': [ESP12_1.LONG_ACCEL],
'yaw_rate_ws': [yaw_rate_ws],
}
)
# yaw_rate_model을 계산함
# yaw_rate_model = model_yaw_rate.predict_yaw_rate(df_input)
yaw_rate_model = model_yaw_rate.predict(df_input)
## 그래프와 판넬 출력을 위한 시슽템 변수 업데이트
# 시스템 변수 calc.yaw_rate_ws에위에서 계산한 yaw_rate_ws를 넣는다.
app.set_system_var_double("calc.yaw_rate_ws", yaw_rate_ws)
# 시스템 변수 calc.yaw_rate_ws_filt에 위에서 계산한 yaw_rate_ws_filt를 넣는다.
app.set_system_var_double("calc.yaw_rate_ws_filt", yaw_rate_ws_filt)
# 시스템 변수 calc.yaw_rate_model에 위에서 계산한 yaw_rate_model를 넣는다.
app.set_system_var_double("calc.yaw_rate_model", yaw_rate_ws_filt)
return # calc_yaw_rate_ws_filt()
결론
- 판넬 기능으로 GUI를 만들고, GUI의 위젯을 시스템 변수와 연결하고, 시스템 변수를 미니프로그램에서 불러와서 연산에 반영할 수 있다.
- 이 방법은 전혀 복잡하지 않다.