inha-cvl / SightShareX

An innovative project designed for autonomous vehicles, enabling them to detect objects and share their types and locations with other vehicles in real-time.
0 stars 0 forks source link

Implement sharing strategy through V2X #1

Open kka-na opened 2 months ago

kka-na commented 2 months ago
kka-na commented 2 months ago

Sample Code 수정 + Python으로 옮기기 +ROS 통합

본 프로젝트는 Extensible V2V 통신만 사용하기 때문에 기존 Sample코드를 간소화 하여 사용. 기존 Sample Code는 c 기반 이기 때문에 테스트에 용이하게 Python코드로 수정. 모든 코드는 하나의 PC에 두개의 OBU장치를 연결하여 통신 테스트 까지 완료한 상태.

  1. main 코드 기본적으로 V2V Sharing 클래스와 RosManager가 동작을 함. 만들어진 V2V Sharing코드가 인자로 들어가서 execute에 사용됨. https://github.com/inha-cvl/SightShareX/blob/f37c1eabcf4f78b4a0557a42a8c0a5e7670c88ef/v2x/main.py#L5-L17 type은 Sender==1 과 Receiver==2를 구분하기 위함. (같은 네트워크에서 테스트 시 ethernet interface를 달리하기 위함) sender일때는 Tx만 동작, receiver일 때는 Rx만 동작.

  2. ROS Manager코드 ROS protocol을 설정한 후에 V2V Sharing내의 set obu함수를 이용하여 WSR registration 및 Tx, Rx에 필요한 변수들을 설정한다. 그 후에 설정한 Rate에 맞추어서 V2V 통신을 수행한다. https://github.com/inha-cvl/SightShareX/blob/f37c1eabcf4f78b4a0557a42a8c0a5e7670c88ef/v2x/ros_manager.py#L27-L49

  3. V2V Sharing코드 socket handler클래스를 생성한다. https://github.com/inha-cvl/SightShareX/blob/f37c1eabcf4f78b4a0557a42a8c0a5e7670c88ef/v2x/v2v_sharing.py#L4-L7 이후에 RosManager에서 set obu함수가 호출되면 socket connecting, WSR registration ( V2V 통신이기 때문에 기본적으로 PSID 58200 설정 ) 그리고 Tx, Rx에 사용하는 self 변수를 설정한다. https://github.com/inha-cvl/SightShareX/blob/f37c1eabcf4f78b4a0557a42a8c0a5e7670c88ef/v2x/v2v_sharing.py#L10-L23 Sender일 경우와 Receiver일 경우 각각 따로 동작한다. https://github.com/inha-cvl/SightShareX/blob/f37c1eabcf4f78b4a0557a42a8c0a5e7670c88ef/v2x/v2v_sharing.py#L25-L34 추후에는 else문만 동작하여 정보를 서로 주고받을 수 있도록 한다. (현재는 단방향 통신만 확인)

kka-na commented 2 months ago

Sharing Information을 위한 구조체 생성

c로 구현된 기존의 sample code의 structure와 interface를 각각 v2x_ext.py, v2x_interface.py로 저장하여 사용한다. 이때 python의 ctypes 모듈을 사용하여 C 타입의 데이터 구조체를 정의한다.

[기존의 C-type 구조체 "V2x_App_Hdr"]

typedef struct _V2x_App_Hdr
{
    char        magic[4];
    uint16_t    len;            // network byte oder
    uint16_t    seq;            // network byte oder
    uint16_t    payload_id;     // network byte oder
    uint8_t     data[0];
}__attribute__((__packed__)) V2x_App_Hdr;

[Python을 이용한 구조체 정의 "V2x_Add_Hdr"]

class V2x_App_Hdr(Structure):
    _pack_ = 1
    _fields_ = [("magic", c_char * 4),
                ("len", c_uint16),
                ("seq", c_uint16),
                ("payload_id", c_uint16),
                ("data", c_uint8*0)]

**Sharing Information 과 Object Information"

3 에서 ROS protocol을 위해 만든 Custom Message와 비슷한 포맷으로 구조체를 정의하여 V2V메시지 송수신시에도 이용한다.

[Sharing Information] 크기: 45 byte + ( path 길이 * 16 (x,y 8byte 씩) ) 범위: 45 ~ 845(경로 길이 50으로 제한) c_double을 c_float으로 바꾸면 : 최대 428

Field Name Type Byte Size
tx_cnt c_uint32 4
rx_cnt c_uint32 4
state c_uint8 1
latitude c_double 8
longitude c_double 8
heading c_double 8
velocity c_double 8
path_x c_double array of 50 400
path_y c_double array of 50 400
obstacle_num c_uint16 2
obstacle ObstacleInformation*20 660
class SharingInformation(Structure):
    _pack_ = 1
    _fields_ = [
        ("tx_cnt", c_uint32),
        ("rx_cnt", c_uint32),
        ("state", c_uint8),
        ("latitude", c_double),
        ("longitude", c_double),
        ("heading", c_double),
        ("velocity", c_double),

        ("path_x", c_double*8),
        ("path_y", c_double*8),
        ("obstacle_num", c_uint16),
        ("obstacle", ObstacleInformation*0)
    ]

[ObstacleInformation] 크기: 33byteObjstacle갯수 범위: 33~660 byte ( Obstacle Maximum 20개로 제한 ) c_float으로 바꾸면 1720 = 340

Field Name Type Byte Size
cls c_uint8 1
enu_x c_double 8
enu_y c_double 8
heading c_double 8
velocity c_double 8
class ObstacleInformation(Structure):
    _pack_ = 1
    _fields_ = [
        ("cls", c_uint8),
        ("enu_x", c_double),
        ("enu_y", c_double),
        ("heading", c_double),
        ("velocity", c_double)
    ]

Feature Map을 추가한다면 float32로 보낼 경우, 3232 pixel 사이즈의 feature map, 4byte = 4096 byte float16으로 보낼 경우 6464 pixel 사이즈의 featuer map, 2byte = 8192byte

kka-na commented 2 months ago

Socket Connection

python에서 socket 통신을 위해 connection setting하는 부분. https://github.com/inha-cvl/SightShareX/blob/f37c1eabcf4f78b4a0557a42a8c0a5e7670c88ef/v2x/libs/socket_handler.py#L20-L37

만약 같은 장치에서 사용한다면 interface 구분을 위하여 self.type값에 따라 network interface 를 설정한다 ( 이는 ifconfig 를 이용하여 확인할 수 있으며, socket handler의 self.interface_list 를 수정해야한다 )

WSR Registration 기존에 PSID를 등록하는 부분이다. 연결 해제시 항상 registration을 수행해야하며, 본 프로젝트에서는 코드 실행시마다 등록을 한다.

get_base는 다른 함수에서 중복사용되는 함수이다. 네트워크로 보내기 위한 데이터 저장소인 buf 를 정의하고, hdr ( V2V Header) object 를 생성하여 return 한다. 이때 반환되는 것은 pointer이며, 비어있는 MAX_SIZE의 buf의 시작 부분의 address가 반환된다. https://github.com/inha-cvl/SightShareX/blob/f37c1eabcf4f78b4a0557a42a8c0a5e7670c88ef/v2x/libs/socket_handler.py#L159-L165

https://github.com/inha-cvl/SightShareX/blob/f37c1eabcf4f78b4a0557a42a8c0a5e7670c88ef/v2x/libs/socket_handler.py#L39-L55 주소로 넘어온 header에 len, seq, payload_id값을 넣어준다. 이후는 data부분이며 payload_id까지의 주소 값을 cast함수를 이용하여 V2x_APP_WSR_ADD_Crc 포인터에 할당한다. 이를 이용하여 WSR action 값과 psid값을 넣어준다. 데이터까지 넣은 이후에 마지막 2byte 에 CrC를 계산한다. 이는 단순히 정의된 look up table에서 값을 찾아 할당한다.