我目前正在将一个鲁棒的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)
之类的数据来访问数据。注意:上面的字节交换代码未经测试;稍后再尝试进行编译,并在必要时进行修复。没有更多信息,我无法为您提供确定的方法,但这也许足以帮助您自己解决问题。