모종의 음모/CAN2025. 2. 19. 16:35

 

$ modprobe vcan
modprobe: ERROR: could not insert 'vcan': Operation not permitted

$ sudo modprobe vcan
sudo ip link add dev vcan0 type vcan

$ ifconfig
br-638c83b169eb: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.18.0.1  netmask 255.255.0.0  broadcast 172.18.255.255
        ether 02:42:d5:e6:f1:21  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:40:63:97:cb  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

enxf8e43b9b776b: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.220.108  netmask 255.255.0.0  broadcast 192.168.255.255
        inet6 fe80::81f4:65ad:f7cc:2f2c  prefixlen 64  scopeid 0x20<link>
        ether f8:e4:3b:9b:77:6b  txqueuelen 1000  (Ethernet)
        RX packets 3619726  bytes 2156366501 (2.1 GB)
        RX errors 0  dropped 106170  overruns 0  frame 0
        TX packets 1452518  bytes 317915291 (317.9 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 160829  bytes 14028478 (14.0 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 160829  bytes 14028478 (14.0 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

wlo1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.220.107  netmask 255.255.0.0  broadcast 192.168.255.255
        inet6 fe80::104b:d69c:878f:cfaa  prefixlen 64  scopeid 0x20<link>
        ether 8c:55:4a:28:25:bc  txqueuelen 1000  (Ethernet)
        RX packets 809871  bytes 90255020 (90.2 MB)
        RX errors 0  dropped 99865  overruns 0  frame 0
        TX packets 53067  bytes 6125665 (6.1 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

$ ifconfig -a
br-638c83b169eb: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.18.0.1  netmask 255.255.0.0  broadcast 172.18.255.255
        ether 02:42:d5:e6:f1:21  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:40:63:97:cb  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

enxf8e43b9b776b: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.220.108  netmask 255.255.0.0  broadcast 192.168.255.255
        inet6 fe80::81f4:65ad:f7cc:2f2c  prefixlen 64  scopeid 0x20<link>
        ether f8:e4:3b:9b:77:6b  txqueuelen 1000  (Ethernet)
        RX packets 3620125  bytes 2156544266 (2.1 GB)
        RX errors 0  dropped 106183  overruns 0  frame 0
        TX packets 1452676  bytes 317938700 (317.9 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 160841  bytes 14030154 (14.0 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 160841  bytes 14030154 (14.0 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

vcan0: flags=128<NOARP>  mtu 72
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 1000  (UNSPEC)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

wlo1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.220.107  netmask 255.255.0.0  broadcast 192.168.255.255
        inet6 fe80::104b:d69c:878f:cfaa  prefixlen 64  scopeid 0x20<link>
        ether 8c:55:4a:28:25:bc  txqueuelen 1000  (Ethernet)
        RX packets 809990  bytes 90270371 (90.2 MB)
        RX errors 0  dropped 99877  overruns 0  frame 0
        TX packets 53074  bytes 6126348 (6.1 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

$ sudo ifconfig vcan0 up
$ ifconfig
br-638c83b169eb: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.18.0.1  netmask 255.255.0.0  broadcast 172.18.255.255
        ether 02:42:d5:e6:f1:21  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:40:63:97:cb  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

enxf8e43b9b776b: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.220.108  netmask 255.255.0.0  broadcast 192.168.255.255
        inet6 fe80::81f4:65ad:f7cc:2f2c  prefixlen 64  scopeid 0x20<link>
        ether f8:e4:3b:9b:77:6b  txqueuelen 1000  (Ethernet)
        RX packets 3620430  bytes 2156573250 (2.1 GB)
        RX errors 0  dropped 106197  overruns 0  frame 0
        TX packets 1452764  bytes 317953427 (317.9 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 160841  bytes 14030154 (14.0 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 160841  bytes 14030154 (14.0 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

vcan0: flags=193<UP,RUNNING,NOARP>  mtu 72
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 1000  (UNSPEC)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

wlo1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.220.107  netmask 255.255.0.0  broadcast 192.168.255.255
        inet6 fe80::104b:d69c:878f:cfaa  prefixlen 64  scopeid 0x20<link>
        ether 8c:55:4a:28:25:bc  txqueuelen 1000  (Ethernet)
        RX packets 810099  bytes 90278671 (90.2 MB)
        RX errors 0  dropped 99889  overruns 0  frame 0
        TX packets 53074  bytes 6126348 (6.1 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[링크 : https://ola-page.tistory.com/66]

 

 

 

$ candump 
candump - dump CAN bus traffic.

Usage: candump [options] <CAN interface>+
  (use CTRL-C to terminate candump)

Options:
         -t <type>   (timestamp: (a)bsolute/(d)elta/(z)ero/(A)bsolute w date)
         -H          (read hardware timestamps instead of system timestamps)
         -c          (increment color mode level)
         -i          (binary output - may exceed 80 chars/line)
         -a          (enable additional ASCII output)
         -S          (swap byte order in printed CAN data[] - marked with '`' )
         -s <level>  (silent mode - 0: off (default) 1: animation 2: silent)
         -l          (log CAN-frames into file. Sets '-s 2' by default)
         -L          (use log file format on stdout)
         -n <count>  (terminate after reception of <count> CAN frames)
         -r <size>   (set socket receive buffer to <size>)
         -D          (Don't exit if a "detected" can device goes down.
         -d          (monitor dropped CAN frames)
         -e          (dump CAN error frames in human-readable format)
         -x          (print extra message infos, rx/tx brs esi)
         -T <msecs>  (terminate after <msecs> without any reception)

Up to 16 CAN interfaces with optional filter sets can be specified
on the commandline in the form: <ifname>[,filter]*

Filters:
  Comma separated filters can be specified for each given CAN interface:
    <can_id>:<can_mask>
         (matches when <received_can_id> & mask == can_id & mask)
    <can_id>~<can_mask>
         (matches when <received_can_id> & mask != can_id & mask)
    #<error_mask>
         (set error frame filter, see include/linux/can/error.h)
    [j|J]
         (join the given CAN filters - logical AND semantic)

CAN IDs, masks and data content are given and expected in hexadecimal values.
When the can_id is 8 digits long the CAN_EFF_FLAG is set for 29 bit EFF format.
Without any given filter all data frames are received ('0:0' default filter).

Use interface name 'any' to receive from all CAN interfaces.

Examples:
candump -c -c -ta can0,123:7FF,400:700,#000000FF can2,400~7F0 can3 can8

candump -l any,0~0,#FFFFFFFF
         (log only error frames but no(!) data frames)
candump -l any,0:0,#FFFFFFFF
         (log error frames and also all data frames)
candump vcan2,12345678:DFFFFFFF
         (match only for extended CAN ID 12345678)
candump vcan2,123:7FF
         (matches CAN ID 123 - including EFF and RTR frames)
candump vcan2,123:C00007FF
         (matches CAN ID 123 - only SFF and non-RTR frames)

 

$ cansend vcan0
cansend - send CAN-frames via CAN_RAW sockets.

Usage: cansend <device> <can_frame>.

<can_frame>:
 <can_id>#{data}          for 'classic' CAN 2.0 data frames
 <can_id>#R{len}          for 'classic' CAN 2.0 data frames
 <can_id>##<flags>{data}  for CAN FD frames

<can_id>:
 3 (SFF) or 8 (EFF) hex chars
{data}:
 0..8 (0..64 CAN FD) ASCII hex-values (optionally separated by '.')
{len}:
 an optional 0..8 value as RTR frames can contain a valid dlc field
<flags>:
 a single ASCII Hex value (0 .. F) which defines canfd_frame.flags

Examples:
  5A1#11.2233.44556677.88 / 123#DEADBEEF / 5AA# / 123##1 / 213##311223344 /
  1F334455#1122334455667788 / 123#R / 00000123#R3

 

아래는 데이터 출력 포맷 확인용

인터페이스 / CAN id / 길이 / 데이터(페이로드 길이)

receive send
$ candump vcan0
  vcan0  111   [5]  01 02 03 04 05
$ cansend vcan0 111#010203.04.05
  vcan0  112   [5]  01 02 03 04 05 $ cansend vcan0 112#010203.04.05
  vcan0  112   [0]  $ cansend vcan0 112#
  vcan0  112  [00] $ cansend vcan0 112##1
  vcan0  112  [01]  23 $ cansend vcan0 112##123
  vcan0  112   [0]  remote request $ cansend vcan0 112#R
  vcan0  112   [3]  remote request $ cansend vcan0 112#R3

 

받는 쪽에서 CAN id 제한할 경우, 112를 받도록 설정했기에 113은 무시된다.

   
$ candump vcan0,112:FF $ cansend vcan0 111#R3
  vcan0  112   [3]  remote request $ cansend vcan0 112#R3
  $ cansend vcan0 113#R3
  vcan0  112   [5]  01 02 03 04 05 $ cansend vcan0 112#010203.04.05
  vcan0  112   [6]  01 02 03 04 05 06 $ cansend vcan0 112#010203.04.0506
  vcan0  112   [7]  01 02 03 04 05 06 07 $ cansend vcan0 112#010203.04.0506.07
  vcan0  112   [0]  remote request $ cansend vcan0 112#R
$ cansend vcan0 112#R10
$ cansend vcan0 112#R100
  vcan0  112   [1]  remote request $ cansend vcan0 112#R1
  vcan0  112   [2]  remote request $ cansend vcan0 112#R2
  vcan0  112   [8]  remote request $ cansend vcan0 112#R8

 

그나저나 mask 라는데 이해가 안되네..

123 = 0x7B & 0x7F0 하면 0x7B가 되어야 하니 16개에 대해서 받아들여야 할 거 같은데 왜 119에서 130 까지 12개 받아들여 질까?

$ candump vcan0,123:7F0
  vcan0  120   [0]  remote request
  vcan0  121   [0]  remote request
  vcan0  122   [0]  remote request
  vcan0  123   [0]  remote request
  vcan0  124   [0]  remote request
  vcan0  125   [0]  remote request
  vcan0  126   [0]  remote request
  vcan0  127   [0]  remote request
  vcan0  128   [0]  remote request
  vcan0  129   [0]  remote request
$ cansend vcan0 119#R
$ cansend vcan0 120#R
$ cansend vcan0 121#R
$ cansend vcan0 122#R
$ cansend vcan0 123#R
$ cansend vcan0 124#R
$ cansend vcan0 125#R
$ cansend vcan0 126#R
$ cansend vcan0 127#R
$ cansend vcan0 128#R
$ cansend vcan0 129#R
$ cansend vcan0 130#R

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

can invader  (0) 2024.01.09
CAN(controller area network)  (0) 2023.10.31
mcp2515 can  (0) 2023.10.30
CAN 통신 우선순위  (0) 2015.01.23
Posted by 구차니

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

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

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

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

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

 

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

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

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

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

github 에 작성중인 코드 푸시!  (0) 2024.12.28
yaw roll pitch  (0) 2024.12.27
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 구차니

어우. 올리기 빡세네

 

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

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

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
dirt rally 2.0 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 구차니

node.js 이동경로  3d로 그리기 등

[링크 : https://github.com/austinbaccus/forza-telemetry/]

 

c#, 텍스트

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

 

M5Stack-CoreS3 기반

Horizon은 324 byte?

 if (packet.length() > 310 && packet.length() < 332) // packet length now 331 for motorsport?
                         {                                                   // Check we have a correctly-sized Forza packet. Note Horizon packets are 324 bytes, Motorsport packets are 311 bytes
                             if (packet.length() == 324)
                             {
                                //  USBSerial.println("Got Horizon packet");
                             }
                            else
                             { // Motorsport packet
                             }
                         }

[링크 : https://github.com/richstokes/Forza-TCS/tree/master]

 

python

[링크 : https://github.com/nettrom/forza_motorsport]

 

golang, 웹기반

[링크 : https://github.com/richstokes/Forza-data-tools]

Posted by 구차니

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 구조체 인가?

구조체 두개를 비교해보니, 실린더 수까진 동일하고 그 이후로 추가 데이터가 들어온다.

그렇다면.. 가속도가 맞다는건데.. 도대체(?) 왜 기어랑은 브레이크는 값이 왜 안들어 올까!

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

 

리눅스 / 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);
}

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

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
Posted by 구차니