324 바이트를 받고 있고
데이터 포맷이 맞는지 모르겠지만 일단은 pause / racing은 확실한데..
가속도 값이 저게 맞나..?
324 received let's fly acc X 10.054599 acc Y -0.817630 acc Z 2.089930 vel X -6.518519 vel Y -0.198055 vel Z 17.591864 yaw -2.862235 roll -0.191706 pitch 0.158119 |
packed 하지 않으면 아래 사이즈
232 sizeof(FORZA_SLED) 332 sizeof(FORZA_DASH) |
packed 하면 아래 사이즈
232 sizeof(FORZA_SLED) 331 sizeof(FORZA_DASH) |
forza horizon 은 sled 보단 dash 구조체 인가?
구조체 두개를 비교해보니, 실린더 수까진 동일하고 그 이후로 추가 데이터가 들어온다.
그렇다면.. 가속도가 맞다는건데.. 도대체(?) 왜 기어랑은 브레이크는 값이 왜 안들어 올까!
리눅스 / ncurses / c 니까 어디든 쉽게 이식은 가능하겠지?
소스코드
더보기
#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;
// 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(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 %f / %f", 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 %d", forza.CarOrdinal);
mvprintw(row++, 0, "CarClass %d", forza.CarClass);
mvprintw(row++, 0, "CarPerformanceIndex %d", forza.CarPerformanceIndex);
mvprintw(row++, 0, "DrivetrainType %d", forza.DrivetrainType);
mvprintw(row++, 0, "NumCylinders %d", forza.NumCylinders);
mvprintw(row++, 0, "clutch[%d] brake[%d] accel[%d] handbrake[%d] gear[%d]"
, forza.Clutch
, forza.Brake
, forza.Accel
, forza.HandBrake
, forza.Gear);
}
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_SLED)\n", str_len, sizeof(FORZA_SLED));
parse_forza(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);
}
'모종의 음모 > force feedback' 카테고리의 다른 글
forza horizon 4 telemetry 수정 (0) | 2024.12.07 |
---|---|
forza telemetry (0) | 2024.12.02 |
forza horizon 4 data format (0) | 2024.11.20 |
dirt rally 2.0 motion data (0) | 2024.11.03 |
F1 2015 motion data (0) | 2024.11.03 |