티스토리 툴바


posted by ppiazi 2011/03/21 15:14
Creative Commons License
Creative Commons License

결론 : GUID를 재시작할때마다 Unique하게 만들자!!


Relevant versions: RTI Data Distribution Service 4.x


For dynamic discovery to work properly, RTI Data Distribution Service relies on a "globally unique identifier" (GUID) that uniquely identifies each instance of a participant in the network. By default, RTI Data Distribution Service will automatically choose values for the host ID and app ID that will generate unique GUIDs for different participant instances. This is documented in the WIRE_PROTOCOL QosPolicy (See [DomainParticipantQoS]).

Currently, RTI Data Distribution Service bases the host ID on the IPv4 address of the host (although this might change in the future). The app ID is calculated from the process (or task) ID and a counter that is incremented per new participant created in the process.

Note that the app ID is not based upon the participant index. When restarting an application with the same participant index, the application should announce itself as a new participant (with a different GUID) on the network, so other participants can respond with their configuration info. Therefore, RTI Data Distribution Service will assign it a different app ID, even if the participant uses the same participant index (and ports). After all, it is a different instance of this participant. If the app ID were unchanged, remote participants would simply interpret the announcement as an "I am still alive" message and not reply with their own information.

On many real-time operating systems, and even on some non-real-time operating system, when a node is rebooted, and applications are automatically started, process ids are deterministically assigned. That is, when the system restarts or if an application dies and is restarted, the application will be reassigned the same process or task ID. If this occurs before other applications in the system can detect that the previous application has died, the new application will appear to be the same as the previous application due to their identical GUIDs.

In such cases, to prevent duplicate GUIDs, you can set the host ID and/or app ID manually using the WIRE_PROTOCOL QosPolicy before creating the participant.

In publisher_main):

struct DDS_DomainParticipantQos participant_qos;

...

// Initialize participant_qos with default values

DDS_DomainParticipantFactory_get_default_participant_qos(

 

               DDS_TheParticipantFactory,

               &participant_qos);

 

// set the rtps host and/or app id.

participant_qos.wire_protocol.rtps_host_id = aRandomOrIncrementingValue;

participant_qos.wire_protocol.rtps_app_id = aRandomOrIncrementingValue;

 

// Create participant using modified DDS_DomainParticipantQos

participant = DDS_DomainParticipantFactory_create_participant(

 

      DDS_TheParticipantFactory, domainId, &participant_qos,

      NULL /* listener */, DDS_STATUS_MASK_NONE);

 

When the application is restarted, RTI DDS assigns it a different host and app ID -- in which case the GUID becomes unique and other applications will recognize this as a new instance of an application and will exchange discovery information.

 

Displaying the GUID

One can observe the GUID using RTI Protocol Analyzer with Wireshark or by turning on high verbosity output level for both the subscriber and publisher.

 

Set the NDDS_Config_LogCategory to NDDS_CONFIG_LOG_CATEGORY_ENTITIES to log messages pertaining to local and remote entities and to the discovery process.

 

NDDS_Config_Logger_set_verbosity_by_category(        NDDS_Config_Logger_get_instance(), NDDS_CONFIG_LOG_CATEGORY_ENTITIES,       NDDS_CONFIG_LOG_VERBOSITY_STATUS_ALL);

 

Look for the following line in output from both subscriber and publisher applications:

DISCDynamicParticipantSelfAnnouncer_enable:announcing participant: 0x7F000001,0x00100001,0x000001C1

 

The GUID is composed of three parts:

1. host ID: identifies the host on which the participant is running

2. app ID: uniquely identifies a particular instance of a participant on this host

3. object ID: has a fixed value in the case of a participant. Will be used to uniquely identify entities (pubs, subs) that belong to the participant.
저작자 표시 비영리 동일 조건 변경 허락
posted by ppiazi 2011/03/14 21:01
Creative Commons License
Creative Commons License

특정 IP를 가지는 NIC에서 RTI DDS를 사용하기 위한 방법이다. Method 2번으로 해결함.


[Applies to RTI Data Distribution Service 4.x]

On a machine with multiple NICs, you can restrict RTI Data Distribution Service traffic to a subset of the available network interfaces (NICs). For example, this would allow you to segregate DDS traffic from other application-specific data.

Selecting specific NICs involves configuring a transport plugin. For details on how this is done, see the HTML documentation under Modules, Programming How-To's, Transport Use Cases. The relevant section is called "Changing the properties of the automatically registered builtin transports."

The following members of the NDDS_Transport_Property_t struct should be set:

* allow_interfaces_list and allow_interfaces_list_length (to use only the specified interfaces)

or

* deny_interfaces_list and deny_interfaces_list_length (to disable only the specified interfaces).

The allow/deny lists are arrays of strings which are used to match the IP address of the interfaces (e.g., "10.10.1.123"). The * wildcard can be used to match a pattern of addresses. For example, to choose the NIC that is on the 10.10.0.0/16 network, use the string "10.10.*" to select the NIC. Alternatively, on most platforms the name of the interface may be used (e.g., "eth0" for the first Ethernet interface on a Linux system).

 

It should be noted that the allow and deny lists determine:

  • The set of interfaces used for the input ports.
  • The set of interfaces that multicast will use for output (if multicast is available on those interfaces).
  • The set of interfaces that will be put in the participant builtin topic data (which informs the remote participant(s) how to contact this participant).

The allow and deny lists have NO effect on unicast output. (This is controlled by the operating system routing table.)

There are three methods for selecting a subset of interfaces:

1.     Use the transport settings

2.     Use the DomainParticipant's Property QoS

3.     Use an XML QoS file

Older versions don't support all three -- see below for which methods are applicable for particular RTI versions.

 

Method 1 - Use the Transport Settings (all 4.x versions)

 

1. Before creating the DomainParticipant, make sure the DomainParticipant will be created in a disabled state. For example, in C++:

    

    retcode = DDSTheParticipantFactory->get_qos(factory_qos);

  factory_qos.entity_factory.autoenable_created_entities = DDS_BOOLEAN_FALSE;

  retcode = DDSTheParticipantFactory->set_qos(factory_qos);

 

2. Get the builtin transports and set the allowed interfaces.

 

3. Call set_builtin_transport_property() before the DomainParticipant is enabled. For example, in C++:

  #define NIC_IP "10.10.*"

  struct NDDS_Transport_UDPv4_Property_t property = NDDS_TRANSPORT_UDPV4_PROPERTY_DEFAULT;
             
  if (NDDSTransportSupport::get_builtin_transport_property
     (participant, DDS_TRANSPORTBUILTIN_UDPv4,
     (struct NDDS_Transport_Property_t&)property) != DDS_RETCODE_OK)
  {
      printf("***Error: get builtin transport property\n");                           
  }   

  /* Set the allowed interface(s) */
  property.parent.allow_interfaces_list = new char*[1];
  property.parent.allow_interfaces_list[0] = new char[strlen(NIC_IP)+1];

  strcpy(property.parent.allow_interfaces_list[0], NIC_IP);
  property.parent.allow_interfaces_list_length = 1;

  if (NDDSTransportSupport::set_builtin_transport_property
             (participant, DDS_TRANSPORTBUILTIN_UDPv4,
             (struct NDDS_Transport_Property_t&)property) != DDS_RETCODE_OK)
  {
    printf("***Error: set builtin transport property\n");                          
  }

    To deny a subset of interfaces, you would do exactly the same as above, but use
    "deny_interfaces_list" instead of "allow_interfaces_list".


4. Enable the DomainParticipant:

  retcode = participant->enable();

    The allow/deny lists are only used during transport initialization; after the DomainParticipant has been enabled, you may dispose of the memory allocated for them.


Method 2 - Use the DomainParticipant's Property QoS  (versions 4.2 and higher)

 

This method involves using the Property QosPolicy to modify the UDP builtin transport properties.

(The Property QoS policy is available in RTI Data Distribution Service 4.2 and higher.) This method is easier than Method 1 because you do not need to create the DomainParticipant disabled first.

 

1. Get the participant_qos and add the properties you want to modify to the QoS:

 

  #define NIC_IP   "10.10.*"

  #define NIC_IP_2 "10.15.*" 

 

  retcode = DDSTheParticipantFactory->get_default_participant_qos(domainparticipant_qos);

  if (retcode != DDS_RETCODE_OK) {

      puts("Error, impossible get default participant qos");

      return NULL;

  }

 

  retcode = DDSPropertyQosPolicyHelper::add_property (

              domainparticipant_qos.property,

              "dds.transport.UDPv4.builtin.parent.deny_interfaces",

              NIC_IP_2, DDS_BOOLEAN_FALSE);

 

  if (retcode != DDS_RETCODE_OK) {

      printf("Error, impossible add property1");

      return NULL;

  }

 

    retcode = DDSPropertyQosPolicyHelper::add_property(
              domainparticipant_qos.property,
              "dds.transport.UDPv4.builtin.parent.allow_interfaces"
,
                           
NIC_IP, DDS_BOOLEAN_FALSE);

   
if (retcode != DDS_RETCODE_OK) {
      printf("Error, impossible add property2");
      return NULL;
  }

2. Create the DomainParticipant.

 

Method 3 - Use an XML QoS Profile (version 4.3 and higher)


This method uses an XML QoS profile to configure the DomainParticipant and transport properties.

 

<dds>
  <qos_library name="test">
    <qos_profile name="UDPv4_properties">
      <participant_qos>
        <property>   
          <value>

            <element>

              <name>dds.transport.UDPv4.builtin.parent.deny_interfaces</name>

              <value>10.15.*</value>

            </element> 

            <element>
              <name>dds.transport.UDPv4.builtin.parent.allow_interfaces</name>
              <value>10.10.*,192.168.*</value>

            </element>            
          </value>
        </property>
      </participant_qos>
    </qos_profile>
  </qos_library>
</dds>


If you are using RTI Data Distribution Service 4.3e, you must call DDSTheParticipantFactory->load_profiles() before

creating the DomainParticipant with a profile.


When using RTI Data Distribution Service 4.4 and higher, the XML file can be automatically loaded.

If NDDS_QOS_PROFILES.xml is in the $NDDSHOME/resource/xml directory, it will be automatically loaded.

Similarly, if USER_QOS_PROFILES.xml is in the working directory, it will be automatically loaded.

See the User’s Manual for more details on XML file loading.


When using version RTI Data Distribution Service 4.4 and higher, place the attached USER_QOS_PROFILES.xml file

in the working directory.

저작자 표시 비영리 동일 조건 변경 허락
posted by ppiazi 2010/11/15 21:29
Creative Commons License
Creative Commons License
RTI DDS를 Vxworks에서 구동할 때 쓰레드 생성 기본 설정으로 VX_FP_TASK가 빠져있어 해당 Listener에서 실수 연산시 예기치 못한 에러가 발생할 수 있다. 이에 아래의 옵션을 켜주어야 한다.

C:\Program Files\RTI\ndds.4.5c\include\ndds\osapi 폴더의 osapi_thread.h 을 열어 아래를 수정한다.

/* #define RTI_OSAPI_THREAD_OPTION_DEFAULT     0x00 */
#define RTI_OSAPI_THREAD_OPTION_DEFAULT     0x01 /* modified by Joohyun Lee 2010.11.15 */

와 같이 수정을 한다.

QoS를 설정하는 더 좋은 방법이 있겠지만.. 일단은 이렇게 땜빵을 ㅎ;
저작자 표시 비영리 동일 조건 변경 허락
posted by ppiazi 2010/09/04 14:24
Creative Commons License
Creative Commons License
1. 예제 파일 작성
 rtiddsgen -language C++ -example ppc604Vx6.6gcc4.1.2 HelloWorld.idl -ppDisable

 생성된 예제파일들을 .h와 .cxx 파일들을 DKM 프로젝트로 생성된 폴더에 복사를 하여 사용한다.

2. DKM 프로젝트 생성 및 환경설정
2.1 VxWorks Image Project 생성하여 다음의 설정을 활성화한다.
Components
  C++ components >> standard library
                          >> C++ compiler support routines
                          >> C++ core runtime
                          >> run static initializers

2.2 Downloadable Kernel Module 프로젝트를 생성하여, Build Properties를 다음과 같이 설정한다.
Build Macro 탭
  DEFINES 에 -DRTI_VXWORKS 추가
  CC_ARCH_SPEC 에 -mlongcall 추가
  LIBPATH에 -L/{RTI DDS 라이브러리 폴더} 추가
  LIBS에 -nddscppz -nddscz -lnddscorez 추가
 
Build Paths 탭
  $(NDDSHOME)/include 와 $(NDDSHOME)/include/ndds 의 패쓰를 아래와 같이 추가.
  -IC:/Program Files/RTI/ndds.4.5c/include
  -IC:/Program Files/RTI/ndds.4.5c/include/ndds

저작자 표시 비영리 동일 조건 변경 허락
posted by ppiazi 2010/02/13 22:10
Creative Commons License
Creative Commons License
2월 9/10일 구로디지털단지 에이스트로닉스에서 RTI DDS 교육을 다녀왔다.
교육을 들으면서, springnote에 적은 내용을 링크를건다.


내용정리는 차차 시간이 날때마다 할 예정이다.
언젠가는 나도 이런 멋진 플랫폼 개발을 할 수 있었으면 하는... >.<

  1. RTI Overview
  2. DDS Introduction
  3. Basic QoS
  4. Discovery
  5. Keys
  6. Reliability
  7. Batching
  8. Listeners & Waitsets
  9. Waitsets in Detail
  10. AsynchPub
  11. Threading
  12. XML QoS Configuration
  13. Statistics API
  14. Debugging & Performance




저작자 표시 비영리 동일 조건 변경 허락
TAG
posted by ppiazi 2009/10/07 21:08
Creative Commons License
Creative Commons License
본 문서를 작성시 환경은 다음과 같다.
  • RTI DDS 4.4d
  • Portable Ubuntu Linux Hardy 8.04

1. license를 요청한다.
  • http://www.rti.com/ 에서 30일 Trial 라이센스를 요청한다.
  • 라이센스 신청시 받는 이메일을 확인하여, 리눅스용 바이너리를 다운로드 받는다.

2. Red Hat Enterprise 5.0 용 RTI DDS 바이너리를 받는다.
  • 설치한 환경은 Portable Ubuntu 8.04 버전이다.
  • i86 gcc 4.1.1 용 버전을 받았다.(물론 x64용 리눅스 사용자는 x64용 바이너리를 받는다.)

3. PATH를 설정한다.
     다운로드한 RTI DDS의 압축을 해제한 디렉토리를 NDDSHOME 이란 환경 변수로 설정을 해주어야 하며, 각종 스크립트 사용을 위해, $NDDSHOME/scripts 를 PATH 환경 변수에 추가를 해주어야 한다.(항상 PATH지정후 에는 export를 잊지말자.)

3.1. NDDSHOME 환경 변수 생성
     전 계정에 적용을 원한다면 /etc/profile에 추가를 하고, 특정 계정에 추가를 원한다면, ~/.bashrc 에 추가하도록 한다. 이메일로 수신한 라이센스 파일(license.dat)을 $NDDSHOME에 복사를 하거나, 실행 파일이 있는 디렉토리에 넣는다.

NDDSHOME=RTI DDS 디렉토리루트

3.2. PATH에 scripts 폴더 추가
     마찬가지로 PATH 환경 변수에 RTI DDS를 위한 실행 스크립트 경로를 추가한다.

PATH=$PATH:$NDDSHOME/scripts

4. 예제 만들기
4.1. IDL 만들기
     HelloWorld.idl 파일을 다음과 같이 작성한다.

#define MAX_CHAR 100

struct HelloWorld
{
    char name[MAX_CHAR];
};

4.2. rtiddsgen 수행
     -language 옵션으로 C++ 용 코드를 생성하게 하고, -example 옵션으로 i86Linux2.6gcc4.1.1 용 예제 publisher와 subscriber를 생성하게 한다.

rtiddsgen -language C++ -example -i86Linux2.6gcc4.1.1 HelloWorld.idl

     자동 생성되는 파일 목록은 다음과 같다.
HelloWorld.cxx
HelloWorld.h
HelloWorldPlugin.cxx
HelloWorldPlugin.h
HelloWorldSupport.cxx
HelloWorldSupport.h
HelloWorld_publisher.cxx
HelloWorld_subscriber.cxx
USER_QOS_PROFILES.xml
makefile_HelloWorld_i86Linux2.6gcc4.1.1

4.3. 빌드하기
      자동 생성된 makefile_HelloWorld_i86Linux2.6gcc4.1.1로 빌드를 한다.
make -f makefile_HelloWorld_i86Linux2.6gcc4.1.1

     빌드된 결과물은 해당 디렉토리 밑에 objs/i86Linux2.6gcc4.1.1 에 생긴다.


4.4. 수행하기
      publisher와 subscriber를 차례대로 수행한다. 오고가는 메시지들을 모니터링하기 위해 rtispy를 동시에 수행하였다. 수행결과는 아래와 같다.



저작자 표시 비영리 동일 조건 변경 허락