我目前正在将一个鲁棒的IMU驱动程序转换为roscpp,并且很难弄清这段代码的作用以及如何翻译它。

def ReqConfiguration(self):
    """Ask for the current configuration of the MT device.
    Assume the device is in Config state."""
    try:
        masterID, period, skipfactor, _, _, _, date, time, num, deviceID,\
                length, mode, settings =\
                struct.unpack('!IHHHHI8s8s32x32xHIHHI8x', config)
    except struct.error:
        raise MTException("could not parse configuration.")
    conf = {'output-mode': mode,
            'output-settings': settings,
            'length': length,
            'period': period,
            'skipfactor': skipfactor,
            'Master device ID': masterID,
            'date': date,
            'time': time,
            'number of devices': num,
            'device ID': deviceID}
    return conf

我必须承认,我以前从未使用过ros和python。
这不是源代码中的1:1代码,我删除了我认为自己知道的代码行,但是尤其是try块是我不了解的代码。我会非常感激您的帮助,因为我有足够的时间保证。

如果有人好奇(因上下文原因):我要翻译的文件是mtdevice.py,mtnode.py和mtdef.py,可以在谷歌中找到文件名和关键字ROS IMU Driver

非常感谢。

最佳答案

要使用C++做同样的事情,您需要声明带有各种参数的struct:

struct DeviceRecord {
    uint32_t masterId;
    uint16_t period, skipfactor, _a, _b;
    uint32_t _c;
    char date[8];
    char time[8];
    char padding[64];
    uint16_t num;
    uint32_t deviceID;
    uint16_t length, mode;
    uint32_t settings;
    char padding[8];
};

(很可能已经在某个地方声明了该结构;它也可能使用“unsigned int”代替“uint32_t”,使用“unsigned short”代替“uint16_t”,并且_a,_b,_c可能具有真实名称。)

一旦有了结构,问题就是如何获取数据。这取决于数据的位置。如果在文件中,则应执行以下操作:
DeviceRecord rec; // An instance of the struct, whatever it's called
std::ifstream fin("yourfile.txt", std::ios::binary);
fin.read(reinterpret_cast<char*>(&rec), sizeof(rec));
// Now you can access rec.masterID etc

另一方面,如果它在内存中某处(即,您有一个char *或void *),那么您只需要强制转换即可:
void* data_source = get_data(...); // You'd get this from somewhere
DeviceRecord* rec_ptr = reinterpret_cast<DeviceRecord*>(stat_source);
// Now you can access rec_ptr->masterID etc

如果您有std::vector,则可以轻松获得这样的指针:
std::vector<uint8_t> data_source = get_data(...); // As above
DeviceRecord* rec_ptr = reinterpret_cast<DeviceRecord*>(data_source.data());
// Now you can access rec_ptr->masterID etc, provided data_source remains in scope. You should probably also avoid modifying data_source.

这里还有一个问题。您收到的数据采用大端格式,但是除非您拥有PowerPC或其他异常处理器,否则您可能使用的是低端格式的计算机。因此,在访问数据之前,需要进行一些字节交换。您可以使用以下功能来执行此操作。
template<typename Int>
Int swap_int(Int n) {
    if(sizeof(Int) == 2) {
        union {char c[2]; Int i;} swapper;
        swapper.i = n;
        std::swap(swapper.c[0], swapper.c[1]);
        n = swapper.i;
    } else if(sizeof(Int) == 4) {
        union {char c[4]; Int i;} swapper;
        swapper.i = n;
        std::swap(swapper.c[0], swapper.c[3]);
        std::swap(swapper.c[1], swapper.c[2]);
        n = swapper.i;
    }
    return n;
}

它们返回交换后的值,而不是就地更改,因此现在您可以使用swap_int(rec->num)之类的数据来访问数据。注意:上面的字节交换代码未经测试;稍后再尝试进行编译,并在必要时进行修复。

没有更多信息,我无法为您提供确定的方法,但这也许足以帮助您自己解决问题。

10-08 16:13