我目前正在翻译一个罗间谍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代码,我删除了行,我认为我知道他们做什么,但特别是尝试块是什么,我不明白。我真的很感激你的帮助,因为我有很长的时间。
如果有人好奇(上下文原因):我必须翻译的文件是mtdevice.py、mtnode.py和mtdef.py,可以在googleing中找到文件名+关键字ROS驱动程序。
提前谢谢。
发布于 2015-07-01 14:30:57
要对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“而不是"uint32_t”,而不是"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)的内容访问数据。注意:上面的字节交换代码是未经测试的;稍后我将尝试编译它,并在必要时修复它。
如果没有更多的信息,我不能给你一个明确的方法,但也许这将足以帮助你自己解决它。
发布于 2015-07-01 13:51:25
这段代码解压缩了C结构的字段,即masterID、句点、跳过因子、_、日期、时间、num、deviceID、长度、模式、设置,将这些字段存储在Python字典中,并将字典作为调用结果返回。下划线是结构中没有使用的部分的占位符。
还请参见:https://docs.python.org/2/library/struct.html,例如,关于格式字符串('!IHHHHI8s8s32x32xHIHHI8x')的描述,它告诉解包函数结构是什么样的。
语法a,b,c,d=f ()意味着函数返回一个在Python中称为tuple的东西。通过将一个元组分配给多个变量,它被分割成它的字段。
示例:
t = (1, 2, 3, 4)
a, b, c, d = t
# At this point a == 1, b == 2, c == 3, d == 4用C++替换这段代码不应该太难,因为C++有与C非常相似的结构,所以requestConfiguration最简单的C++实现就是返回该结构。如果您希望更接近于Python功能,您的函数可以将结构的字段放入C++ STL映射中并返回该字段。格式字符串+链接指向的文档,告诉您结构中的数据类型和位置。
注意,它是unpack的第二个参数,它保存了数据,第一个参数只包含关于第二个参数的布局(格式)的信息,如链接中所解释的那样。第二个参数看起来好像是一个字符串,但实际上它是一个C结构。第一个参数告诉Python在哪里可以找到该结构中的内容。
因此,如果读取格式字符串上的文档,就可以找到第二个参数( strings )的布局。但也许你不需要。这取决于函数的调用方。它可能只是期望普通的C结构。
从您添加的评论中,我了解到您的函数中的代码比显示的要多。结构的字段被分配给类的属性。
如果您知道C struct (config)的字段名,那么可以将它们直接分配给C++类的属性。
// Pointer 'this' isn't needed but inserted for clarity
this->mode = config.mode;
this->settings = config.settings;
this->length = config.length;我假设配置结构的字段名确实是模式、设置、长度等,但您必须验证这一点。这个结构的布局可能是在某些C头文件(或文档中)中声明的。
https://stackoverflow.com/questions/31163199
复制相似问题