아래 소스를 참고하고

[링크  : https://github.com/geeooff/forza-data-web/blob/main/Console/ForzaDataConsole.cs]

 

원본 포맷도 참고해서

[링크 : https://support.forzamotorsport.net/hc/en-us/articles/21742934024211-Forza-Motorsport-Data-Out-Documentation]

 

몇가지 단위 수정함

영국놈들(!) 이라서 출력이 watt가 아니라 hp(horse power)로 되어있고

속도고 mph를 기본으로 던져주고

온도고 섭씨가 아니라 화씨.. 어우

[링크 : https://github.com/minimonk82/forza_horizon_4_telemetry]

 

아무튼.. 서보를 이용해서 서스펜션 길이를 가지고 장난질 치면 조금 수월하게 작업할수 있으려나?

라즈베리 파이 pico로 시리얼로 서스펜션 길이만 전송하고

pwm 4개 채널로 서보 제어해서 적당하게 맞춰봐야겠다.

Posted by 구차니

내부 ui에서 출력되는 것과 비교중

tirewear 등은 안 맞는것 같고

suspension도 딱 맞지 않는 느낌.

 

아래는 그냥 nc로 엔터쳐서 아무값도 안가 오류난 건데 아무튼..

타이어/서스펜션은 앞-좌/우 , 뒤-좌/우 라서 두 줄에 우겨넣어 출력함

 

[링크 : https://github.com/minimonk82/forza_horizon_4_telemetry]

Posted by 구차니

게임내에서 제공되는 텔레메트리 정보인데

프로토콜에서 제공되는 내용보다 더 다양한거 같다?

켜놓으면 재미있긴 한데 지도가 사라져서 아쉽..

 

없어 보이는 데이터로는

손상 /  타이어 온도 / 타이어 정보(압력)

 

여기부터는 udp telemetry에 있는 값들 같다.

Posted by 구차니

수직 동기화 켜면 30 / 60fps 가능하고

수직 동기화 끄고 프레임 속도 고정 해제(가변) 하면

120fps 정도 까지 올라가는데 그럴 때에는 8ms 주기로 온다.

어디서 주워듣기로는 물리엔진은 2배 빠르게 계산한다는데 그거랑 별개로

데이터 전송 주기는 프레임 속도에 맞추는 건가?

 

단순하게 roll/pitch를 이용해서 기울기를 표현하려고 했더니

서킷에서 기울기에 따라 roll이 올라가야 할 것 같은데.. 싶은 부분에서 pitch가 올라가고 그러는걸 보면

yaw/roll/pitch는 global 좌표에서의 값으로 생각된다.

'모종의 음모 > motion simulator' 카테고리의 다른 글

forza horizon 4 telemetry 검증중  (0) 2025.10.02
forza horizon 4 - telemetry ui  (0) 2025.09.28
github 에 작성중인 코드 푸시!  (0) 2024.12.28
yaw roll pitch  (0) 2024.12.27
HS-311 스텝모터  (0) 2024.12.26
Posted by 구차니

어우. 올리기 빡세네

 

[링크 : https://github.com/minimonk82/forza_horizon_4_telemetry]

'모종의 음모 > motion simulator' 카테고리의 다른 글

forza horizon 4 - telemetry ui  (0) 2025.09.28
forza horizon 수직동기화와 telemetry 정보  (0) 2025.01.01
yaw roll pitch  (0) 2024.12.27
HS-311 스텝모터  (0) 2024.12.26
f1 2015 telemetry udp  (0) 2024.12.08
Posted by 구차니

telemetry 정보에서 자동차임에도 불구하고

yaw roll pitch가 나와서 어떻게 매칭을 해야 하나 고민했는데

 

yaw는 이동방향, 나침반으로 어딜 보고 있냐를 표시하면 될 것 같고

이전 각도와의 차이로 차의 회전 방향을 알 수 있을테니 얜 미분을 해야하나?

 

roll은 측면으로 구르는 각도(그래서 roll cage 인가?)

좌우로 기운 도로를 달리게 되면 요 녀석의 값이 달라질 것 같고

 

pitch는 앞뒤로 오르막 내리막 길을 가게 되면 값이 달라질 것 같다.

 

정리하면.. 모션 시뮬레이터에서는 roll과 pitch로 운전석의 기울기를 표현하면 될 것 같고

yaw의 미분 값의 방향으로 시계, 반시계 방향의 운동량을 표현하면 될 것 같다.

 

가속도 값으로는 z 축은 의자 자체를 떨구거나 올리기 힘들테니 6축 아니면 힘들 것 같고

x 축은 앞뒤로 기울기고

y 축은 좌우로 기울이면 될테니

 

사용자가 느끼는 관성의 방향은

x 축 <-> yaw,

y 축 <-> pitch 와는 반대의 방향으로 나타나게 되겠네?

그러면.. 감각을 속이려면 yaw, roll 보단

x,y 가속도 값이 더 중요할 것 같다.

Vertical axis (yaw)
The yaw axis has its origin at the center of gravity and is directed towards the bottom of the aircraft, perpendicular to the wings and to the fuselage reference line. Motion about this axis is called yaw. A positive yawing motion moves the nose of the aircraft to the right.[1][2] The rudder is the primary control of yaw.[3]

The term yaw was originally applied in sailing, and referred to the motion of an unsteady ship rotating about its vertical axis. Its etymology is uncertain.[4]

Lateral axis (pitch)
The pitch axis (also called transverse or lateral axis),[5] passes through an aircraft from wingtip to wingtip. Rotation about this axis is called pitch. Pitch changes the vertical direction that the aircraft's nose is pointing (a positive pitching motion raises the nose of the aircraft and lowers the tail). The elevators are the primary control surfaces for pitch.[3]

Longitudinal axis (roll)
The roll axis (or longitudinal axis[5]) has its origin at the center of gravity and is directed forward, parallel to the fuselage reference line. Motion about this axis is called roll. An angular displacement about this axis is called bank.[3] A positive rolling motion lifts the left wing and lowers the right wing. The pilot rolls by increasing the lift on one wing and decreasing it on the other. This changes the bank angle.[6] The ailerons are the primary control of bank. The rudder also has a secondary effect on bank.[7]

[링크 : https://en.wikipedia.org/wiki/Aircraft_principal_axes]

[링크 : https://velog.io/@sobokii/UE5-Roll-Pitch-Yaw]

 

주익의 에일러론이 둘 다 움직이면 어떻게 될까 궁금했는데,

일단 구조적으로 양쪽이 반대로 움직이게 되어있어서 안된다고 하고

된다고 하더라도.. 무게중심에 가까워서 엘리베이션과는 다르게 움직일 것 같단 의견

플랩을 내리면 에일러론을 둘다 내린 형상이 되니

둘 다 내리면 수직방향으로 AoA이 커진 채로 올라가고

둘 다 올리면 수직방향으로 AoA가 커진채로 내려가려나?

[링크 : https://www.clien.net/service/board/park/15063368]

 

두서없이 쓰다 보니 먼 소리인지... 잠을 자야하나?!

'모종의 음모 > motion simulator' 카테고리의 다른 글

forza horizon 수직동기화와 telemetry 정보  (0) 2025.01.01
github 에 작성중인 코드 푸시!  (0) 2024.12.28
HS-311 스텝모터  (0) 2024.12.26
f1 2015 telemetry udp  (0) 2024.12.08
dirt rally 2.0 telemetry udp  (0) 2024.12.08
Posted by 구차니

스텝모터 데이터 시트를 보는데

4.8V ~ 6.0V 입력가능하고

6.0V 일 경우 최대 800mA 를 소모한다. 생각외로.. 많이 먹네? 4.8W 라.. (역률 인지 먼지 이런건 모르니 패스)

아무튼 모터 두개를 동시에 풀로 돌린다고 가정하면

1.6A는 흘려주어야 한다는 건데.. 일반적인 보조배터리라면 5V 2A는 되니까

라즈베리 등을 작동 시키는데에만도 빠듯하다는 의미가 될 듯..

아무튼 60도에 0.15~0.19초

0.0025초/1도 3msec 라니 물리적으로는 상당히 빠른 편이라고 해줘야 하나?

 

 

[링크 : https://www.devicemart.co.kr/goods/view?no=11225]

'모종의 음모 > motion simulator' 카테고리의 다른 글

github 에 작성중인 코드 푸시!  (0) 2024.12.28
yaw roll pitch  (0) 2024.12.27
f1 2015 telemetry udp  (0) 2024.12.08
dirt rally 2.0 telemetry udp  (0) 2024.12.08
forza horizon 4 telemetry 수정  (0) 2024.12.07
Posted by 구차니

다시 프로그램 수정해서 받아보니 패킷의 길이가 시원하게 보여서 좋긴하네

nc는 패킷의 시작을 알 수 없어서 매번 아쉽다.

 

/YF로 나오는 녀석은 패킷의 거의 마지막 부분이었군

280 received, 343 sizeof(FORZA_DASH)

83 0A B0 42 28 0F 0C 42 BA 7F 8B 44 BA 7F 8B 44 
AB 05 3D C4 8C 0F 8B 40 C8 54 DA C3 46 BE 2F 40 
1B E5 B8 BF B2 5E CD 3C 4C 74 15 40 5A 9B 58 3F 
13 BE C8 BC 41 4D 08 3F E3 4A 08 3F 4D 98 0B BC 
49 B1 58 BF BB F3 D4 3F C8 41 A4 3F EA 88 DA 3F 
88 4C B0 3F 35 F8 B4 C1 FE 29 31 C1 D3 61 96 C1 
FA 6F DF C0 8A DD 30 C0 AE D2 30 C0 7A E2 30 C0 
4D D1 30 C0 00 00 00 00 00 00 00 80 00 00 00 00 
00 00 00 00 00 00 00 00 15 49 87 BB C1 3D D5 3D 
00 00 00 00 06 01 3B 45 00 00 00 00 00 00 80 41 
00 50 C3 48 00 50 C3 48 00 00 00 00 00 00 80 3F 
00 00 80 3F 96 3D 13 41 00 00 C8 42 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 BB 50 42 44 
E9 01 42 44 49 C5 54 44 9F EA 54 44 00 00 90 41 
00 00 90 41 00 00 90 41 00 00 90 41 00 00 80 40 
00 00 C6 42 40 AA A5 45 00 00 00 00 FF 2F 59 46 
00 80 3B 45 00 00 10 41 00 00 80 3F 00 00 00 00 
00 00 00 00 00 00 00 40 

 

280 바이트의 시작과 끝 매칭

$ nc -ul 20777 | hexdump -C
00150bd0  0f 3d a4 42 11 35 3c 42  1f 26 f0 44 1f 26 f0 44  |.=.B.5
00150be0  6a 66 35 c3 d3 e9 5b 40  5c bb 65 c4 d5 14 e5 40  |jf5...[@\.e....@|
00150bf0  31 da a3 40 9d d7 b3 bd  3d 12 a0 c0 2c 1f 31 3f  |1..@....=...,.1?|
00150c00  30 a1 52 ba bf d5 38 3f  59 cb 38 3f ef b2 a5 bc  |0.R...8?Y.8?....|
00150c10  ae 16 31 bf ca b0 41 40  1e 4d 4d 40 14 bb 72 40  |..1...A@.MM@..r@|
00150c20  13 8e 6b 40 d6 ed 1b 42  86 5f 09 43 04 a5 45 42  |..k@...B._.C..EB|
00150c30  02 81 3c 43 22 f3 e3 40  12 9d e5 40 f1 40 e4 40  |..
00150c40  34 af e5 40 00 00 00 00  f0 70 68 3d 00 00 00 00  |4..@.....ph=....|
00150c50  00 00 00 00 00 00 00 40  02 a4 0f be 13 8f 8d be  |.......@........|
00150c60  00 00 00 00 87 86 6d 45  00 00 00 00 00 00 80 41  |......mE.......A|
00150c70  00 50 c3 48 00 50 c3 48  00 00 00 00 00 00 80 3f  |.P.H.P.H.......?|
00150c80  00 00 80 3f 77 16 0f 41  00 00 c8 42 00 00 00 00  |...?w..A...B....|
00150c90  00 00 80 3f 98 68 2d 42  00 00 00 00 a2 1e 76 44  |...?.h-B......vD|
00150ca0  fc 37 76 44 37 e5 84 44  24 b4 84 44 00 00 90 41  |.7vD7..D$..D...A|
00150cb0  00 00 90 41 00 00 90 41  00 00 90 41 00 00 80 40  |...A...A...A...@|
00150cc0  00 00 c6 42 40 aa a5 45  00 00 00 00 ff 2f 59 46  |...B@..E..... /YF |
00150cd0  00 80 3b 45 00 00 10 41  00 00 80 3f 00 00 00 00  |..;E...A...?....|
00150ce0  00 00 00 00 00 00 00 40  97 45 a4 42 1c 46 3c 42  |.......@.E.B.F

'모종의 음모 > motion simulator' 카테고리의 다른 글

yaw roll pitch  (0) 2024.12.27
HS-311 스텝모터  (0) 2024.12.26
dirt rally 2.0 telemetry udp  (0) 2024.12.08
forza horizon 4 telemetry 수정  (0) 2024.12.07
forza telemetry  (0) 2024.12.02
Posted by 구차니

68byte 라서,17 개의 float 데이터 일 것 같은데 매칭되는게 없어 보이네?

 

가장 처음꺼는 timestamp 같은데

가장 마지막의 ToCA는 먼지 모르겠고..

float 형으로 해도 int 형으로 해도 먼가 의미를 지니는 패킷을 찾긴 쉽지 않네..

68 received, 343 sizeof(FORZA_DASH)

0D A9 01 00 90 B3 A2 3F EB B4 CA 3D 94 9B 23 BF 
1A BA 3B 40 2B 3A E4 3D E8 46 E5 3F A1 BE E9 BF 
7F 16 E1 3E ED 9A 23 C1 27 43 06 BF 64 1A 84 C0 
AA 38 EF BF 00 C3 E7 FA 0E 13 2C FE 00 2D A6 08 
54 6F 43 41 
--------------
108813 0.000000
1067627408 1.271105
1036694763 0.098978
-1088185452 -0.639093
1077656090 2.933234
1038367275 0.111439
1071990504 1.791226
-1075200351 -1.826130
1054938751 0.439625
-1054631187 -10.225324
-1090108633 -0.524462
-1065084316 -4.128222
-1074841430 -1.868917
-85474560 -601687822097128628961607183025307648.000000
-30665970 -57181538217263035746945707264998113280.000000
145108224 0.000000
1094938452 12.214680

[링크 : https://github.com/gabrielgouv/dirt-rally-telemetry-dashboard/blob/main/src/main/java/com/github/gabrielgouv/dr2td/model/TelemetryData.java]

[링크 : https://github.com/ozkar99/cm-telemetry/blob/master/src/dirt/rally2.rs]

[링크 : https://docs.google.com/spreadsheets/d/1eA518KHFowYw7tSMa-NxIFYpiWe5JXgVVQ_IMs7BVW0/edit?gid=0#gid=0]

'모종의 음모 > motion simulator' 카테고리의 다른 글

HS-311 스텝모터  (0) 2024.12.26
f1 2015 telemetry udp  (0) 2024.12.08
forza horizon 4 telemetry 수정  (0) 2024.12.07
forza telemetry  (0) 2024.12.02
forza horizon 4, 리눅스용 c언어 대시보드  (0) 2024.11.30
Posted by 구차니

빌드하려고 vs2022 부터 다시 깔고 쑈하긴 했는데

아무튼 기어가 올라오긴 한다.

 

서버는 자기 자신의 아이피를 넣고(0.0.0.0을 넣으면 되려나?) 포트를 게임에서 설정한대로 하면 끝

 

이 녀석의 구조체를 뜯어 봐야 겠구만?

[링크 : https://github.com/geeooff/forza-data-web]

 

 

다시 원점으로 돌아가서 하나하나 길이 맞추면서 보니까 먼가 12바이트가 추가되어 있었다.

01 00 00 00 // S32 IsRaceOn;

87 65 A8 14 // U32 TimestampMS;
FB 6F 14 46 // F32 EngineMaxRpm;
F8 FF 47 44 // F32 EngineIdleRpm;
D9 18 0A 45 // F32 CurrentEngineRpm;

C0 FC 1B BD // F32 AccelerationX;
90 AB 60 3D 
6C 00 D9 40 

88 EA A9 BD // F32 VelocityX;
E8 EF 9D BC 
83 62 9B 40 

5D F5 9C 3B // F32 AngularVelocityX;
16 7C 65 BC 
E9 09 D0 BC 

7E D0 B0 BF // F32 Yaw;
F2 E8 B1 BE 
AA F7 69 3E 

FA 31 DB 3E // F32 NormalizedSuspensionTravelFrontLeft
CE 72 B3 3E 
A4 DD F8 3E 
3F 6E 03 3F 

FB 1B 71 3F // F32 TireSlipRatioFrontLeft
07 85 59 3F 
A2 BE 10 3F 
4F 86 29 3F 

39 74 A3 41 // F32 WheelRotationSpeedFrontLeft
CC 09 8C 41 
BC CC 81 41 
C2 F8 85 41 

00 00 00 00 // S32 WheelOnRumbleStripFrontLeft
00 00 00 00 
00 00 00 00 
00 00 00 00 

00 00 00 00 // F32 WheelInPuddleDepthFrontLeft
00 00 00 00 
00 00 00 00 
00 00 00 00 

99 99 19 3F // F32 SurfaceRumbleFrontLeft
99 99 19 3F 
99 99 19 3F
99 99 19 3F

34 3F DD 3D // F32 TireSlipAngleFrontLeft
34 C6 E3 3D 
0F 9A 97 3D 
35 FA 99 3D 

B2 B0 72 3F  // F32 TireCombinedSlipFrontLeft
06 60 5B 3F 
DA FA 11 3F 
20 9D 2A 3F 

1E A2 B0 BB // F32 SuspensionTravelMetersFrontLeft
5C 44 3D BC 
00 E9 9A 3A 
80 C3 54 3B 

89 0D 00 00 // S32 CarOrdinal
04 00 00 00 // S32 CarClass
84 03 00 00 // S32 CarPerformanceIndex
02 00 00 00 // S32 DrivetrainType - // 0 = FWD, 1 = RWD, 2 = AWD

0C 00 00 00 // S32 NumCylinders
0D 00 00 00 // ?? 
00 00 00 00 // ??
00 00 00 00 // ??

EC C6 18 C4 // F32 PositionX; 
33 08 20 43 // F32 PositionY; 
40 A0 1C C5 // F32 PositionZ; 
A1 68 9B 40 // F32 Speed; 
F4 5F 03 48 // F32 Power; 
23 DF 11 44 // F32 Torque; 
20 4C 9C 42 // F32 TireTempFrontLeft; 
0D 43 9D 42 // F32 TireTempFrontRight; 
9B FD A9 42 // F32 TireTempRearLeft; 
9B FD A9 42 // F32 TireTempRearRight; 
00 00 00 00 // F32 Boost; 
00 00 80 3F // F32 Fuel; 
00 00 00 00 // F32 DistanceTraveled; 
00 00 00 00 // F32 BestLap; 
00 00 00 00 // F32 LastLap;
00 00 00 00 // F32 CurrentLap;
C8 AF FB 43 // F32 CurrentRaceTime;
00 00       // U16 LapNumber;
00          // U8 RacePosition;
FF          // U8 Accel;
00          // U8 Brake;
00          // U8 Clutch;
00          // U8 HandBrake;
01          // U8 Gear;
00          // S8 Steer;
00          // S8 NormalizedDrivingLine;
00          // S8 NormalizedAIBrakeDifference;
00          // ???

 

sled 구조체에서 Steer 이후에 24bit는 원래의 구조체와는 다른 것 같네

아무튼 아래와 같이 값들이 정상적으로 출력되는 것 확인!

 

소스코드

더보기
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <ncurses.h>

 

#define BUF_SIZE 500

 

typedef char S8;
typedef unsigned char U8;
typedef unsigned short U16;
typedef int S32;
typedef unsigned int U32;
typedef float F32;

 

typedef struct _sled_
{
// = 1 when race is on. = 0 when in menus/race stopped …
S32 IsRaceOn;

 

// Can overflow to 0 eventually
U32 TimestampMS;
F32 EngineMaxRpm;
F32 EngineIdleRpm;
F32 CurrentEngineRpm;

 

// In the car's local space; X = right, Y = up, Z = forward
F32 AccelerationX;
F32 AccelerationY;
F32 AccelerationZ;

 

// In the car's local space; X = right, Y = up, Z = forward
F32 VelocityX;
F32 VelocityY;
F32 VelocityZ;

 

// In the car's local space; X = pitch, Y = yaw, Z = roll
F32 AngularVelocityX;
F32 AngularVelocityY;
F32 AngularVelocityZ;

 

F32 Yaw;
F32 Pitch;
F32 Roll;

 

// Suspension travel normalized: 0.0f = max stretch; 1.0 = max compression
F32 NormalizedSuspensionTravelFrontLeft;
F32 NormalizedSuspensionTravelFrontRight;
F32 NormalizedSuspensionTravelRearLeft;
F32 NormalizedSuspensionTravelRearRight;

 

// Tire normalized slip ratio, = 0 means 100% grip and |ratio| > 1.0 means loss of grip.
F32 TireSlipRatioFrontLeft;
F32 TireSlipRatioFrontRight;
F32 TireSlipRatioRearLeft;
F32 TireSlipRatioRearRight;

 

// Wheels rotation speed radians/sec.
F32 WheelRotationSpeedFrontLeft;
F32 WheelRotationSpeedFrontRight;
F32 WheelRotationSpeedRearLeft;
F32 WheelRotationSpeedRearRight;

 

// = 1 when wheel is on rumble strip, = 0 when off.
S32 WheelOnRumbleStripFrontLeft;
S32 WheelOnRumbleStripFrontRight;
S32 WheelOnRumbleStripRearLeft;
S32 heelOnRumbleStripRearRight;

 

// = from 0 to 1, where 1 is the deepest puddle
F32 WheelInPuddleDepthFrontLeft;
F32 WheelInPuddleDepthFrontRight;
F32 WheelInPuddleDepthRearLeft;
F32 WheelInPuddleDepthRearRight;

 

// Non-dimensional surface rumble values passed to controller force feedback
F32 SurfaceRumbleFrontLeft;
F32 SurfaceRumbleFrontRight;
F32 SurfaceRumbleRearLeft;
F32 SurfaceRumbleRearRight;

 

// Tire normalized slip angle, = 0 means 100% grip and |angle| > 1.0 means loss of grip.
F32 TireSlipAngleFrontLeft;
F32 TireSlipAngleFrontRight;
F32 TireSlipAngleRearLeft;
F32 TireSlipAngleRearRight;

 

// Tire normalized combined slip, = 0 means 100% grip and |slip| > 1.0 means loss of grip.
F32 TireCombinedSlipFrontLeft;
F32 TireCombinedSlipFrontRight;
F32 TireCombinedSlipRearLeft;
F32 TireCombinedSlipRearRight;

 

// Actual suspension travel in meters
F32 SuspensionTravelMetersFrontLeft;
F32 SuspensionTravelMetersFrontRight;
F32 SuspensionTravelMetersRearLeft;
F32 SuspensionTravelMetersRearRight;

 

// Unique ID of the car make/model
S32 CarOrdinal;

 

// Between 0 (D -- worst cars) and 7 (X class -- best cars) inclusive
S32 CarClass;

 

// Between 100 (worst car) and 999 (best car) inclusive
S32 CarPerformanceIndex;

 

// 0 = FWD, 1 = RWD, 2 = AWD
S32 DrivetrainType;

 

// Number of cylinders in the engine
S32 NumCylinders;
} __attribute__((packed)) FORZA_SLED;

 

typedef struct _dash_
{
// = 1 when race is on. = 0 when in menus/race stopped …
S32 IsRaceOn;

 

// Can overflow to 0 eventually
U32 TimestampMS;
F32 EngineMaxRpm;
F32 EngineIdleRpm;
F32 CurrentEngineRpm;

 

// In the car's local space; X = right, Y = up, Z = forward
F32 AccelerationX;
F32 AccelerationY;
F32 AccelerationZ;

 

// In the car's local space; X = right, Y = up, Z = forward
F32 VelocityX;
F32 VelocityY;
F32 VelocityZ;

 

// In the car's local space; X = pitch, Y = yaw, Z = roll
F32 AngularVelocityX;
F32 AngularVelocityY;
F32 AngularVelocityZ;

 

F32 Yaw;
F32 Pitch;
F32 Roll;

 

// Suspension travel normalized: 0.0f = max stretch; 1.0 = max compression
F32 NormalizedSuspensionTravelFrontLeft;
F32 NormalizedSuspensionTravelFrontRight;
F32 NormalizedSuspensionTravelRearLeft;
F32 NormalizedSuspensionTravelRearRight;

 

// Tire normalized slip ratio, = 0 means 100% grip and |ratio| > 1.0 means loss of grip.
F32 TireSlipRatioFrontLeft;
F32 TireSlipRatioFrontRight;
F32 TireSlipRatioRearLeft;
F32 TireSlipRatioRearRight;

 

// Wheels rotation speed radians/sec.
F32 WheelRotationSpeedFrontLeft;
F32 WheelRotationSpeedFrontRight;
F32 WheelRotationSpeedRearLeft;
F32 WheelRotationSpeedRearRight;

 

// = 1 when wheel is on rumble strip, = 0 when off.
S32 WheelOnRumbleStripFrontLeft;
S32 WheelOnRumbleStripFrontRight;
S32 WheelOnRumbleStripRearLeft;
S32 heelOnRumbleStripRearRight;

 

// = from 0 to 1, where 1 is the deepest puddle
F32 WheelInPuddleDepthFrontLeft;
F32 WheelInPuddleDepthFrontRight;
F32 WheelInPuddleDepthRearLeft;
F32 WheelInPuddleDepthRearRight;

 

// Non-dimensional surface rumble values passed to controller force feedback
F32 SurfaceRumbleFrontLeft;
F32 SurfaceRumbleFrontRight;
F32 SurfaceRumbleRearLeft;
F32 SurfaceRumbleRearRight;

 

// Tire normalized slip angle, = 0 means 100% grip and |angle| > 1.0 means loss of grip.
F32 TireSlipAngleFrontLeft;
F32 TireSlipAngleFrontRight;
F32 TireSlipAngleRearLeft;
F32 TireSlipAngleRearRight;

 

// Tire normalized combined slip, = 0 means 100% grip and |slip| > 1.0 means loss of grip.
F32 TireCombinedSlipFrontLeft;
F32 TireCombinedSlipFrontRight;
F32 TireCombinedSlipRearLeft;
F32 TireCombinedSlipRearRight;

 

// Actual suspension travel in meters
F32 SuspensionTravelMetersFrontLeft;
F32 SuspensionTravelMetersFrontRight;
F32 SuspensionTravelMetersRearLeft;
F32 SuspensionTravelMetersRearRight;

 

// Unique ID of the car make/model
S32 CarOrdinal;

 

// Between 0 (D -- worst cars) and 7 (X class -- best cars) inclusive
S32 CarClass;

 

// Between 100 (worst car) and 999 (best car) inclusive
S32 CarPerformanceIndex;

 

// 0 = FWD, 1 = RWD, 2 = AWD
S32 DrivetrainType;

 

// Number of cylinders in the engine
S32 NumCylinders;

 

S32 reserved1;
S32 reserved2;
S32 reserved3;

 

// add for DASH
F32 PositionX;
F32 PositionY;
F32 PositionZ;
F32 Speed;
F32 Power;
F32 Torque;
F32 TireTempFrontLeft;
F32 TireTempFrontRight;
F32 TireTempRearLeft;
F32 TireTempRearRight;
F32 Boost;
F32 Fuel;
F32 DistanceTraveled;
F32 BestLap;
F32 LastLap;
F32 CurrentLap;
F32 CurrentRaceTime;
U16 LapNumber;
U8 RacePosition;
U8 Accel;
U8 Brake;
U8 Clutch;
U8 HandBrake;
U8 Gear;
S8 Steer;
S8 NormalizedDrivingLine;
S8 NormalizedAIBrakeDifference;

 

F32 TireWearFrontLeft;
F32 TireWearFrontRight;
F32 TireWearRearLeft;
F32 TireWearRearRight;

 

// ID for track
S32 TrackOrdinal;
} __attribute__((packed)) FORZA_DASH;

 

int last_raceon = 0;
void parse_forza_dbg(unsigned char *message)
{
int row = 0;
FORZA_DASH forza;
memcpy(&forza, message, sizeof(FORZA_DASH));

 

for(int i = 0; i < 324; i++)
{
if(i % 16 == 0)
printf("\n");
printf("%02X ",message[i]);
}
printf("\n");

 

printf("NumCylinders %d\n", forza.NumCylinders);
 
printf("PositionX %f\n", forza.PositionX);
printf("PositionY %f\n", forza.PositionY);
printf("PositionZ %f\n", forza.PositionZ);

 

printf("speed %f\n", forza.Speed);

 

printf("clutch %d\n", forza.Clutch);
printf("brake %d\n", forza.Brake);
printf("accel %d\n", forza.Accel);
printf("HandBrake %d\n", forza.HandBrake);
}

 

void parse_forza(unsigned char *message)
{
int row = 0;
FORZA_DASH forza;
memcpy(&forza, message, sizeof(FORZA_DASH));

 

static unsigned int pack_cnt = 0;

 

if(last_raceon != forza.IsRaceOn)
{
clear();
last_raceon = forza.IsRaceOn;
}

 

if(forza.IsRaceOn)
{
mvprintw(row++, 0, "let's fly %d\n",pack_cnt++);

 

mvprintw(row++, 0, "RPM %.0f / %.0f", forza.CurrentEngineRpm, forza.EngineMaxRpm);

 

mvprintw(row++, 0, "acc X %f", forza.AccelerationX);
mvprintw(row++, 0, "acc Y %f", forza.AccelerationY);
mvprintw(row++, 0, "acc Z %f", forza.AccelerationZ);

 

mvprintw(row++, 0, "vel X %f", forza.VelocityX);
mvprintw(row++, 0, "vel Y %f", forza.VelocityY);
mvprintw(row++, 0, "vel Z %f", forza.VelocityZ);

 

mvprintw(row++, 0, "ang vel X %f", forza.AngularVelocityX);
mvprintw(row++, 0, "ang vel Y %f", forza.AngularVelocityY);
mvprintw(row++, 0, "ang vel Z %f", forza.AngularVelocityZ);
 
mvprintw(row++, 0, "yaw %f", forza.Yaw);
mvprintw(row++, 0, "roll %f", forza.Pitch);
mvprintw(row++, 0, "pitch %f", forza.Roll);

 

mvprintw(row++, 0, "CarOrdinal %5d", forza.CarOrdinal);
mvprintw(row++, 0, "CarClass %5d", forza.CarClass);
mvprintw(row++, 0, "CarPerformanceIndex %5d", forza.CarPerformanceIndex);
mvprintw(row++, 0, "DrivetrainType %5d", forza.DrivetrainType);
mvprintw(row++, 0, "NumCylinders %5d", forza.NumCylinders);

 

mvprintw(row++, 0, "clutch[%3d] brake[%3d] accel[%3d] handbrake[%3d] gear[%2d] Steer[%3d]"
, forza.Clutch
, forza.Brake
, forza.Accel
, forza.HandBrake
, forza.Gear
, forza.Steer
);

 

mvprintw(row++, 0, "Speed[%5.0f] Power[%7.0f] Torque[%5.0f] Boost[%5.0f] Fuel[%5.0f]"
, forza.Speed
, forza.Power
, forza.Torque
, forza.Boost
, forza.Fuel
);

 

mvprintw(row++, 0, "Position %f , %f , %f"
, forza.PositionX
, forza.PositionY
, forza.PositionZ
);
}
else mvprintw(row++, 0, "pause");

 

refresh();
}

 

void error_handling(char *message);

 

int main(int argc, char *argv[]){
int serv_sock;
char message[BUF_SIZE];
int str_len;
socklen_t clnt_adr_sz;

 

struct sockaddr_in serv_adr, clnt_adr;

 

printf("%d sizeof(FORZA_SLED)\n", sizeof(FORZA_SLED));
printf("%d sizeof(FORZA_DASH)\n", sizeof(FORZA_DASH));

 

if(argc!=2){
printf("Usage:%s <port>\n", argv[0]);
exit(1);
}

 

serv_sock = socket(PF_INET, SOCK_DGRAM, 0);
if(serv_sock == -1)
error_handling("UDP socket creation error");

 

memset(&serv_adr, 0, sizeof(serv_adr));
serv_adr.sin_family=AF_INET;
serv_adr.sin_addr.s_addr=htonl(INADDR_ANY);
serv_adr.sin_port=htons(atoi(argv[1]));

 

if(bind(serv_sock, (struct sockaddr*)&serv_adr, sizeof(serv_adr)) == -1)
error_handling("bind() error");
 
initscr();

 

while(1){
clnt_adr_sz = sizeof(clnt_adr);
str_len = recvfrom(serv_sock, message, BUF_SIZE, 0, (struct sockaddr*)&clnt_adr, &clnt_adr_sz);
message[str_len] = 0x00;
// printf("%d received [%s]\n", str_len, message);
// printf("%d received, %d sizeof(FORZA_DASH)\n", str_len, sizeof(FORZA_DASH));
parse_forza(message);
// parse_forza_dbg(message);
sendto(serv_sock, message, str_len, 0, (struct sockaddr*)&clnt_adr, clnt_adr_sz);
}
close(serv_sock);
return 0;
}

 

void error_handling(char *message){
fputs(message, stderr);
fputc('\n', stderr);

 

endwin();
exit(1);
}




'모종의 음모 > motion simulator' 카테고리의 다른 글

f1 2015 telemetry udp  (0) 2024.12.08
dirt rally 2.0 telemetry udp  (0) 2024.12.08
forza telemetry  (0) 2024.12.02
forza horizon 4, 리눅스용 c언어 대시보드  (0) 2024.11.30
forza horizon 4 data format  (0) 2024.11.20
Posted by 구차니