dyubicuoa / OpenRTM_aist_paho_mqtt_interface

MIT License
2 stars 1 forks source link

CDRとJSONの変換をもっと簡単にできないか? #3

Closed Nobu19800 closed 3 years ago

Nobu19800 commented 3 years ago

DataTypeFormat.pyでCDRのデータとJSONの変換処理をデータ型ごとに定義していますが、要はCORBAのデータとdict型の変換なので以下のような関数で処理できないかと思いました。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# -*- Python -*-

import OpenRTM_aist
import RTC
import omniORB

def reserializeFromJsonToData(dictobj, datatype):
    data = OpenRTM_aist.instantiateDataType(datatype)
    for key, val in dictobj.items():
        item = data.__dict__[key]
        if isinstance(val, dict):
            data.__dict__[key] = reserializeFromJsonToData(val, item)
        else:
            data.__dict__[key] = val
    return data

def reserializeFromDataToJson(cdrdata, attrtype):
    if isinstance(attrtype, int):
        desc = [attrtype]
    elif isinstance(attrtype, tuple):
        desc = attrtype
    else:
        desc = omniORB.findType(attrtype._NP_RepositoryId)

    if desc[0] == omniORB.tcInternal.tv_struct:
        arg = {}
        for i in range(4, len(desc), 2):
            attr = desc[i]
            attr_type = desc[i + 1]
            arg[attr] = reserializeFromDataToJson(
                cdrdata.__dict__[attr], attr_type)
        return arg
    else:
        return cdrdata
    return None

dataTimedPose2D = RTC.TimedPose2D(
    RTC.Time(1.0, 2.0), RTC.Pose2D(RTC.Point2D(3.0, 4.0), 5.0))
dataTimedPose2DDict = reserializeFromDataToJson(
    dataTimedPose2D, RTC.TimedPose2D)
print("RTC.TimedPose2D Dict:", dataTimedPose2DDict)
dataTimedPose2DData = reserializeFromJsonToData(
    dataTimedPose2DDict, RTC.TimedPose2D)
print("RTC.TimedPose2D Data:", dataTimedPose2DData)
dataTimedDouble = RTC.TimedDouble(
    RTC.Time(1.0, 2.0), 3.0)
dataTimedDoubleDict = reserializeFromDataToJson(
    dataTimedDouble, RTC.TimedDouble)
print("RTC.TimedDouble Dict:", dataTimedDoubleDict)
dataTimedDoubleData = reserializeFromJsonToData(
    dataTimedDoubleDict, RTC.TimedDouble)
print("RTC.TimedDouble Data:", dataTimedDoubleData)
dataTimedDoubleSeq = RTC.TimedDoubleSeq(
    RTC.Time(1.0, 2.0), [1.0, 2.0, 3.0, 4.0, 5.0])
dataTimedDoubleSeqDict = reserializeFromDataToJson(
    dataTimedDoubleSeq, RTC.TimedDoubleSeq)
print("RTC.TimedDoubleSeq Dict:", dataTimedDoubleSeqDict)
dataTimedDoubleSeqData = reserializeFromJsonToData(
    dataTimedDoubleSeqDict, RTC.TimedDoubleSeq)
print("RTC.TimedDoubleSeq Data:", dataTimedDoubleSeqData)
dyubicuoa commented 3 years ago

アドバイスありがとうございます。コード例について、是非参考にさせていただきソースコードの改善に努めていきたいと思います。改良が終わりましたらその旨ご報告させていただきます。よろしくお願いいたします。

dyubicuoa commented 3 years ago

re-serializeモジュールの改良が完了いたしました。JSON->DataTypeについてはコード例をほぼそのまま使用させていただきました。ただ、jsonをdeserializeした場合の文字列の扱い方がPython2系とPython3系で異なっているので、その部分で若干修正を加えております。DataType->JSONについては、dict属性を持っているか否かで再帰判定を行うようにしました。ご確認いただければ幸いです。 改めましてコード例の方、大変参考になりました。ありがとうございました。

Nobu19800 commented 3 years ago

対応していただいてありがとうございます。

DataType->JSONについては、dict属性を持っているか否かで再帰判定を行うようにしました。

一応、any型を含むデータ型を定義することができるのでその場合どうなるのか少し気になりますが、多分ないと思うのでこのissueは閉じます。