[openrtm-users 00022] Windowsへの移植

5 posts / 0 new
Last post
root
Offline
Last seen: 10 hours 47 min ago
Joined: 2009-06-23 14:31
[openrtm-users 00022] Windowsへの移植

稲村@IHIです。

OpenRTMのWindowsへの移植を計画しています。
もし、すでに行なった人がいたら、はまるであろう注意点など教えていただけないでしょうか。
よろしくお願いします。

# これが初めてなら、人柱として順次報告しますが…

Undefined
root
Offline
Last seen: 10 hours 47 min ago
Joined: 2009-06-23 14:31
[openrtm-users 00023] Windowsへの移植

Dear Ando-san,
Concerning the compilation of OpenRTM under Windows/TAO, here are some
points I whish you follow in future version to avoid compilation errors :

1 - When using CORBA sequences, cast the index to a CORBA::ULong
For example, in RtcManager.cpp line 341 and 342, factory_list[cnt] should be
factory_list[CORBA::ULong(cnt)]

2 - DON'T USE the _CORBA_String_Helper as it is defined only in OmniORB, not
in TAO. One option would be to define an RTM_String_Helper tht could
abstract the differences between ORBs for matters like strings.

3 - In RtcOutport.h line 201 instead of
temp <<= m_Buffer.get_new();
use
*temp <<= m_Buffer.get_new();

Apart from that, OpenRTM could compile properly with Windows / Visual C++ 7.
1 / TAO

Regards,

Olivier Lemaire

-----Original Message-----
From: 稲村 渡 [mailto:wataru_inamura@ihi.co.jp]
Sent: Tuesday, September 13, 2005 10:53 AM
To: openrtm-users@m.aist.go.jp
Subject: [openrtm-users 00022] Windowsへの移植

稲村@IHIです。

OpenRTMのWindowsへの移植を計画しています。
もし、すでに行なった人がいたら、はまるであろう注意点など教えていただけないで
しょうか。
よろしくお願いします。

# これが初めてなら、人柱として順次報告しますが…

root
Offline
Last seen: 10 hours 47 min ago
Joined: 2009-06-23 14:31
[openrtm-users 00031] Windowsへの移植

稲村@IHIです。

ずいぶん時間が経ってしまいましたが、報告します。
VC6で使えるようになりました。

[1] 全般
using namespace std;を削除し、std名前空間を明示する。
これをやらないと、いろいろとコンパイルエラーがでる。
以下のファイルを修正。
RtcBase.h,RtcBase.cpp,
RtcConfig.h,
RtcManager.h,RtcManager.cpp,
RtcModuleProfile.h,RtcModuleProfile.cpp,
RtcNaming.h,RtcNaming.cpp,
RtcOutPort.h,
RtcOutPortBase.h,RtcOutPortBase.cpp,

[2] RtcBase.h

1. USLEEPマクロをVC6で動作するように修正。
#if defined(_MSC_VER) && (_MSC_VER <= 1200)
# define USLEEP(x) Sleep(x/1000);
#else
# define USLEEP(x) usleep(x);
#endif

2. ComponentStateをenumで定義。
VC6ではconstで定義した定数を定数式と判断してくれないためcaseラベルに使えない。 そのため、以下のようにenumで定義しなおした。
数値が一致することを常に確認しなければならない。これは、苦肉の策。もっと良いやり方はないか?
#if defined(_MSC_VER) && (_MSC_VER <= 1200)
enum ComponentStateVC6{
RTC_UNKNOWN = 0,
RTC_BORN = 1,
RTC_INITIALIZING= 2,
RTC_READY = 3,
RTC_STARTING = 4,
RTC_ACTIVE = 5,
RTC_STOPPING = 6,
RTC_ABORTING = 7,
RTC_ERROR = 8,
RTC_FATAL_ERROR = 9,
RTC_EXITING = 10,
};
#else
const ComponentState RTC_UNKNOWN = RTM::RTComponent::RTC_UNKNOWN;
const ComponentState RTC_BORN = RTM::RTComponent::RTC_BORN;
const ComponentState RTC_INITIALIZING = RTM::RTComponent::RTC_INITIALIZING;
const ComponentState RTC_READY = RTM::RTComponent::RTC_READY;
const ComponentState RTC_STARTING = RTM::RTComponent::RTC_STARTING;
const ComponentState RTC_ACTIVE = RTM::RTComponent::RTC_ACTIVE;
const ComponentState RTC_STOPPING = RTM::RTComponent::RTC_STOPPING;
const ComponentState RTC_ABORTING = RTM::RTComponent::RTC_ABORTING;
const ComponentState RTC_ERROR = RTM::RTComponent::RTC_ERROR;
const ComponentState RTC_FATAL_ERROR = RTM::RTComponent::RTC_FATAL_ERROR;
const ComponentState RTC_EXITING = RTM::RTComponent::RTC_EXITING;
#endif

3. friend class ThreadStates; 追加
class ThreadStatesのコンストラクタで使用しているRUNNINGは、
RtcBaseクラスのprotectedのため、エラーとなる。
TreadStatesをRtcBaseのfriendとした。

[3] RtcBase.cpp
1. sleep -> USLEEP

[5] RtcInPort.h
1. m_Bufferの宣言位置変更→gccのWARNING(宣言の順番と初期化並びの順番が前後している)への対処

[6] RtcManager.h
1. class LogEmitterのoperator()が戻り値を返していない。
適当な値(0)を返すように修正。
しかし、この演算子にそもそも戻り値は必要なのか疑問。
class LogEmitter
: public RtcSyncCallback
{
public:
LogEmitter(OutPortAny& port, TimedString& var)
: m_OutPort(port), m_Var(var)
{
}
virtual int operator()(const char* s)
{
m_Var.data = CORBA::string_dup(s);
m_OutPort.write();
return 0; // 追加
}

[7] RtcManager.cpp
1. usleep -> USLEEP
2. CPU負荷100%となる問題に対処
以下のように、2箇所のwhile内に、スリープを入れることで、ビジーループではなくなる。
暫定処置。本当にこれでよいかは要検討。
void RtcManager::runManager()
{
// start POA manager
m_pPOAManager->activate();

if (CORBA::is_nil(m_pORB))
{
RTC_ERROR(("Invalid ORB pointer."));
exit(1);
}
// m_pORB->run();
while (g_mgrActive)
{
USLEEP(1000); // ビジーループ回避のためにスリープを入れる */
if (m_pORB->work_pending()){
m_pORB->perform_work();
}
}
shutdown();

while (m_pORB->work_pending())
{
USLEEP(1000); // ビジーループ回避のためにスリープを入れる */
if (m_pORB->work_pending())
m_pORB->perform_work();
}

[8] RtcModuleProfile.h
1. typedef 名を明示 → VC6の警告に対処
typedef struct RtcModuleProfSpec {
RtcModuleProfileType type;
char* value;
} RtcModuleProfSpec;

[9] RtcModuleProfile.cpp
1. メソッドappendInPortProfile(),appendOutPortProfile()が戻り値を返していない。
適当な値(true)を返すように修正。

[10] RtcNameComponent.cpp
1. メソッドpush()
VC6の問題で、for(int i;...) ... for(int i; )とすると、
intを同じスコープで再定義したことになる。int i; の定義をforの外に置く。

[11] RtcNaming.cpp
1. メソッドpickupNode() が戻り値を返していない。
適当な値(true)を返すように修正。

[12] RtcOutPort.h
1.VC6では、clock_gettimeがなく、ACE_OS::clock_gettimeの実装も何も処理をしていない。

マクロ ACE_HAS_CLOCK_GETTIMEの定義部を以下のように修正。
#if defined(_MSC_VER) && (_MSC_VER <= 1200) // VC6以前
#else
#define ACE_HAS_CLOCK_GETTIME // VC6ではclock_gettimeは存在しない。
#endif
メソッドwrite()を以下のように修正。
#if defined (_MSC_VER) && (_MSC_VER <= 1200) // VC6以前
ts = ACE_OS::gettimeofday();
#else
ACE_OS::clock_gettime(CLOCK_REALTIME, &ts);
#endif

[13] RtcRingBuffer.h
1. メソッドget_backがvirtualになっているのを、inlineに修正。
2.m_Oldestの宣言位置を最後に移動。→gccのWARNING(宣言の順番と初期化並びの順番が前後している)への対処

[14] RtcSubscriber.h
1. メソッドupdate(), svc() のデフォルト実装が戻り値を返していない。
適当な値(trueと0)を返すように修正。

[15] RtcSubscriber.cpp
1. メソッド int SubscriberPeriodic::svc(void)が戻り値を返していない。
 適当な値(0)を返すように修正。
2. sleep(1); -> ACE_OS::sleep( ACE_Time_Value(1,0) );

[16] RtcSystemLogger.h
1. VC6に存在しない定義を追加。
#if defined(_MSC_VER) && (_MSC_VER <= 1200)
# define LINE_MAX 2048
# define vsnprintf _vsnprintf
# define __restrict
#endif

2. std::char_type, std::traits_type
コンパイルエラー「char_type, traits_typeは'std' のメンバではありません。」
が発生するため、以下のように修正。
typedef _CharT char_type;
typedef _Traits traits_type;

3. std::string::basic_string -> std::basic_string
VC6には、std::string::basic_stringがないので以下のように修正。
virtual int sync()
{
std::basic_string<_CharT> s(this->pbase(),
this->pptr() - this->pbase());

4. ERRORマクロとの衝突。
VC6では、WINGDI.HにマクロERRORが定義されている。
#define ERROR 0

以下のように、ERRORを使っているところを、ERROR_に修正。
#if defined(_MSC_VER) && (_MSC_VER <= 1200)
enum {SILENT, ERROR_, WARN, INFO, NORMAL, DEBUG, TRACE, VERBOSE, PARANOID, MANDATORY };
#else
enum {SILENT, ERROR, WARN, INFO, NORMAL, DEBUG, TRACE, VERBOSE, PARANOID, MANDATORY };
#endif

5. 自動変数の配列定義に定数が使われていない。
メソッドgetFmtDate の以下の記述は、コンパイルエラー「定数式が必要です」が発生する。
int maxsize(256);
char buf[maxsize];
次のように修正。これは、VC6が正しいはず。
const int maxsize(256);
char buf[maxsize];

####################################################
ちょっとした機能拡張

[1] 構成ファイル(rtc.conf)の内容を、コンポーネントクラスで利用できるようにする。

たとえば、
rtc.confにシリアルポートの指定を以下のように追加しておいて、
SeralPort /dev/ttyS0

デバイスとシリアルポートで通信するコンポーネントのrtc_init_entryで、
std::stirng port = getCofigValue("SerialPort");
m_dev.Open( port );
などと使えるようにしたい。

1. RtcConfigクラス
(1) コンフィグレーション情報を取得できるように修正。
以下の関数を追加。
/*!
* @if jp
* @brief コンフィグレーション情報取得
* 任意のキーを指定してコンフィグレーション情報を取得する。
* @param a_configKey キー文字列
* @return 値文字列。見つからなかった場合は、空文字列となる。
* @else
* @endif
*/
std::string getConfigValue(
const std::string& a_configKey
) const
{
std::map::const_iterator ci
= m_Config.find(a_configKey);
if( ci != m_Config.end() )
{
return ci->second;
}
else
{
return "";
}
}

2. RtcBaseクラス
/*!
* @brief 構成情報取得
* 任意のキーを指定して構成情報を取得する。
* @param a_configKey キー文字列
* @return 値文字列。見つからなかった場合は、空文字列となる。
*/
std::string getConfigValue(
const std::string& a_configKey
) const
{
return m_pManager->getConfig().getConfigValue(a_configKey);
}

root
Offline
Last seen: 10 hours 47 min ago
Joined: 2009-06-23 14:31
[openrtm-users 00032] Windowsへの移植

稲村様

安藤@産総研です

VC6でコンパイルが通った(というより通した)ということで
ありがとうございます。

次期バージョンに以下の変更を反映させたいと思います。

できれば、修正したソースやプロジェクトファイル等提供
をしていただけないでしょうか?

> 稲村@IHIです。
>
> ずいぶん時間が経ってしまいましたが、報告します。
> VC6で使えるようになりました。
>
>
> [1] 全般
> using namespace std;を削除し、std名前空間を明示する。
> これをやらないと、いろいろとコンパイルエラーがでる。
> 以下のファイルを修正。
> RtcBase.h,RtcBase.cpp,
> RtcConfig.h,
> RtcManager.h,RtcManager.cpp,
> RtcModuleProfile.h,RtcModuleProfile.cpp,
> RtcNaming.h,RtcNaming.cpp,
> RtcOutPort.h,
> RtcOutPortBase.h,RtcOutPortBase.cpp,
>
>
>
> [2] RtcBase.h
>
> 1. USLEEPマクロをVC6で動作するように修正。
> #if defined(_MSC_VER) && (_MSC_VER <= 1200)
> # define USLEEP(x) Sleep(x/1000);
> #else
> # define USLEEP(x) usleep(x);
> #endif
>
> 2. ComponentStateをenumで定義。
> VC6ではconstで定義した定数を定数式と判断してくれないためcaseラベルに使えない。 そのため、以下のようにenumで定義しなおした。
> 数値が一致することを常に確認しなければならない。これは、苦肉の策。もっと良いやり方はないか?
> #if defined(_MSC_VER) && (_MSC_VER <= 1200)
> enum ComponentStateVC6{
> RTC_UNKNOWN = 0,
> RTC_BORN = 1,
> RTC_INITIALIZING= 2,
> RTC_READY = 3,
> RTC_STARTING = 4,
> RTC_ACTIVE = 5,
> RTC_STOPPING = 6,
> RTC_ABORTING = 7,
> RTC_ERROR = 8,
> RTC_FATAL_ERROR = 9,
> RTC_EXITING = 10,
> };
> #else
> const ComponentState RTC_UNKNOWN = RTM::RTComponent::RTC_UNKNOWN;
> const ComponentState RTC_BORN = RTM::RTComponent::RTC_BORN;
> const ComponentState RTC_INITIALIZING = RTM::RTComponent::RTC_INITIALIZING;
> const ComponentState RTC_READY = RTM::RTComponent::RTC_READY;
> const ComponentState RTC_STARTING = RTM::RTComponent::RTC_STARTING;
> const ComponentState RTC_ACTIVE = RTM::RTComponent::RTC_ACTIVE;
> const ComponentState RTC_STOPPING = RTM::RTComponent::RTC_STOPPING;
> const ComponentState RTC_ABORTING = RTM::RTComponent::RTC_ABORTING;
> const ComponentState RTC_ERROR = RTM::RTComponent::RTC_ERROR;
> const ComponentState RTC_FATAL_ERROR = RTM::RTComponent::RTC_FATAL_ERROR;
> const ComponentState RTC_EXITING = RTM::RTComponent::RTC_EXITING;
> #endif
>
> 3. friend class ThreadStates; 追加
> class ThreadStatesのコンストラクタで使用しているRUNNINGは、
> RtcBaseクラスのprotectedのため、エラーとなる。
> TreadStatesをRtcBaseのfriendとした。
>
>
> [3] RtcBase.cpp
> 1. sleep -> USLEEP
>
>
> [5] RtcInPort.h
> 1. m_Bufferの宣言位置変更→gccのWARNING(宣言の順番と初期化並びの順番が前後している)への対処
>
>
> [6] RtcManager.h
> 1. class LogEmitterのoperator()が戻り値を返していない。
> 適当な値(0)を返すように修正。
> しかし、この演算子にそもそも戻り値は必要なのか疑問。
> class LogEmitter
> : public RtcSyncCallback
> {
> public:
> LogEmitter(OutPortAny& port, TimedString& var)
> : m_OutPort(port), m_Var(var)
> {
> }
> virtual int operator()(const char* s)
> {
> m_Var.data = CORBA::string_dup(s);
> m_OutPort.write();
> return 0; // 追加
> }
>
>
> [7] RtcManager.cpp
> 1. usleep -> USLEEP
> 2. CPU負荷100%となる問題に対処
> 以下のように、2箇所のwhile内に、スリープを入れることで、ビジーループではなくなる。
> 暫定処置。本当にこれでよいかは要検討。
> void RtcManager::runManager()
> {
> // start POA manager
> m_pPOAManager->activate();
>
> if (CORBA::is_nil(m_pORB))
> {
> RTC_ERROR(("Invalid ORB pointer."));
> exit(1);
> }
> // m_pORB->run();
> while (g_mgrActive)
> {
> USLEEP(1000); // ビジーループ回避のためにスリープを入れる */
> if (m_pORB->work_pending()){
> m_pORB->perform_work();
> }
> }
> shutdown();
>
> while (m_pORB->work_pending())
> {
> USLEEP(1000); // ビジーループ回避のためにスリープを入れる */
> if (m_pORB->work_pending())
> m_pORB->perform_work();
> }
>
>
>
> [8] RtcModuleProfile.h
> 1. typedef 名を明示 → VC6の警告に対処
> typedef struct RtcModuleProfSpec {
> RtcModuleProfileType type;
> char* value;
> } RtcModuleProfSpec;
>
>
> [9] RtcModuleProfile.cpp
> 1. メソッドappendInPortProfile(),appendOutPortProfile()が戻り値を返していない。
> 適当な値(true)を返すように修正。
>
>
> [10] RtcNameComponent.cpp
> 1. メソッドpush()
> VC6の問題で、for(int i;...) ... for(int i; )とすると、
> intを同じスコープで再定義したことになる。int i; の定義をforの外に置く。
>
>
> [11] RtcNaming.cpp
> 1. メソッドpickupNode() が戻り値を返していない。
> 適当な値(true)を返すように修正。
>
>
> [12] RtcOutPort.h
> 1.VC6では、clock_gettimeがなく、ACE_OS::clock_gettimeの実装も何も処理をしていない。
>
> マクロ ACE_HAS_CLOCK_GETTIMEの定義部を以下のように修正。
> #if defined(_MSC_VER) && (_MSC_VER <= 1200) // VC6以前
> #else
> #define ACE_HAS_CLOCK_GETTIME // VC6ではclock_gettimeは存在しない。
> #endif
> メソッドwrite()を以下のように修正。
> #if defined (_MSC_VER) && (_MSC_VER <= 1200) // VC6以前
> ts = ACE_OS::gettimeofday();
> #else
> ACE_OS::clock_gettime(CLOCK_REALTIME, &ts);
> #endif
>
>
>
> [13] RtcRingBuffer.h
> 1. メソッドget_backがvirtualになっているのを、inlineに修正。
> 2.m_Oldestの宣言位置を最後に移動。→gccのWARNING(宣言の順番と初期化並びの順番が前後している)への対処
>
>
> [14] RtcSubscriber.h
> 1. メソッドupdate(), svc() のデフォルト実装が戻り値を返していない。
> 適当な値(trueと0)を返すように修正。
>
>
> [15] RtcSubscriber.cpp
> 1. メソッド int SubscriberPeriodic::svc(void)が戻り値を返していない。
>  適当な値(0)を返すように修正。
> 2. sleep(1); -> ACE_OS::sleep( ACE_Time_Value(1,0) );
>
>
> [16] RtcSystemLogger.h
> 1. VC6に存在しない定義を追加。
> #if defined(_MSC_VER) && (_MSC_VER <= 1200)
> # define LINE_MAX 2048
> # define vsnprintf _vsnprintf
> # define __restrict
> #endif
>
> 2. std::char_type, std::traits_type
> コンパイルエラー「char_type, traits_typeは'std' のメンバではありません。」
> が発生するため、以下のように修正。
> typedef _CharT char_type;
> typedef _Traits traits_type;
>
> 3. std::string::basic_string -> std::basic_string
> VC6には、std::string::basic_stringがないので以下のように修正。
> virtual int sync()
> {
> std::basic_string<_CharT> s(this->pbase(),
> this->pptr() - this->pbase());
>
>
> 4. ERRORマクロとの衝突。
> VC6では、WINGDI.HにマクロERRORが定義されている。
> #define ERROR 0
>
> 以下のように、ERRORを使っているところを、ERROR_に修正。
> #if defined(_MSC_VER) && (_MSC_VER <= 1200)
> enum {SILENT, ERROR_, WARN, INFO, NORMAL, DEBUG, TRACE, VERBOSE, PARANOID, MANDATORY };
> #else
> enum {SILENT, ERROR, WARN, INFO, NORMAL, DEBUG, TRACE, VERBOSE, PARANOID, MANDATORY };
> #endif
>
>
> 5. 自動変数の配列定義に定数が使われていない。
> メソッドgetFmtDate の以下の記述は、コンパイルエラー「定数式が必要です」が発生する。
> int maxsize(256);
> char buf[maxsize];
> 次のように修正。これは、VC6が正しいはず。
> const int maxsize(256);
> char buf[maxsize];
>
>
>
> ####################################################
> ちょっとした機能拡張
>
> [1] 構成ファイル(rtc.conf)の内容を、コンポーネントクラスで利用できるようにする。
>
> たとえば、
> rtc.confにシリアルポートの指定を以下のように追加しておいて、
> SeralPort /dev/ttyS0
>
> デバイスとシリアルポートで通信するコンポーネントのrtc_init_entryで、
> std::stirng port = getCofigValue("SerialPort");
> m_dev.Open( port );
> などと使えるようにしたい。
>
>
> 1. RtcConfigクラス
> (1) コンフィグレーション情報を取得できるように修正。
> 以下の関数を追加。
> /*!
> * @if jp
> * @brief コンフィグレーション情報取得
> * 任意のキーを指定してコンフィグレーション情報を取得する。
> * @param a_configKey キー文字列
> * @return 値文字列。見つからなかった場合は、空文字列となる。
> * @else
> * @endif
> */
> std::string getConfigValue(
> const std::string& a_configKey
> ) const
> {
> std::map::const_iterator ci
> = m_Config.find(a_configKey);
> if( ci != m_Config.end() )
> {
> return ci->second;
> }
> else
> {
> return "";
> }
> }
>
> 2. RtcBaseクラス
> /*!
> * @brief 構成情報取得
> * 任意のキーを指定して構成情報を取得する。
> * @param a_configKey キー文字列
> * @return 値文字列。見つからなかった場合は、空文字列となる。
> */
> std::string getConfigValue(
> const std::string& a_configKey
> ) const
> {
> return m_pManager->getConfig().getConfigValue(a_configKey);
> }
>
>
>

root
Offline
Last seen: 10 hours 47 min ago
Joined: 2009-06-23 14:31
[openrtm-users 00033] Windowsへの移植

稲村@IHIです。

> 次期バージョンに以下の変更を反映させたいと思います。
>
> できれば、修正したソースやプロジェクトファイル等提供
> をしていただけないでしょうか?
>
了解しました。
安藤さんへ直接送ります。

なお、この修正がVineLinuxで動作することは確認済みです。
VC7は手元にないため、確認できておりません。
おそらく大丈夫だとは思いますが。

Log in or register to post comments

Download

latest Releases : 2.0.0-RELESE

2.0.0-RELESE Download page

Number of Projects

Choreonoid

Motion editor/Dynamics simulator

OpenHRP3

Dynamics simulator

OpenRTP

Integrated Development Platform

AIST RTC collection

RT-Components collection by AIST

TORK

Tokyo Opensource Robotics Association

DAQ-Middleware

Middleware for DAQ (Data Aquisition) by KEK