0

我正在使用从 C 中生成的 Player/Stage SWIG 代码,现在我正在尝试访问一个值指向另一个结构的结构。我想知道如何在 python 中提取结构数组。

C 代码如下所示:

/** @brief Localization device data. */
typedef struct
{
  /** Device info; must be at the start of all device structures. */
  playerc_device_t info;

  /** Map dimensions (cells). */
  int map_size_x, map_size_y;

  /** Map scale (m/cell). */
  double map_scale;

  /** Next map tile to read. */
  int map_tile_x, map_tile_y;

  /** Map data (empty = -1, unknown = 0, occupied = +1). */
  int8_t *map_cells;

  /** The number of pending (unprocessed) sensor readings. */
  int pending_count;

  /** The timestamp on the last reading processed. */
  double pending_time;

  /** List of possible poses. */
  int hypoth_count;
  player_localize_hypoth_t *hypoths;

  double mean[3];
  double variance;
  int num_particles;
  playerc_localize_particle_t *particles;

} playerc_localize_t;

/** @brief Hypothesis format.

Since the robot pose may be ambiguous (i.e., the robot may at any
of a number of widely spaced locations), the @p localize interface is
capable of returning more that one hypothesis. */
typedef struct player_localize_hypoth
{
  /** The mean value of the pose estimate (m, m, rad). */
  player_pose2d_t mean;
  /** The covariance matrix pose estimate (lower half, symmetric matrix) 
      (cov(xx) in m$^2$, cov(yy) in $^2$, cov(aa) in rad$^2$, 
       cov(xy), cov(ya), cov(xa) ). */
  double cov[6];
  /** The weight coefficient for linear combination (alpha) */
  double alpha;
} player_localize_hypoth_t;

python的代码是自动生成的。我正在尝试访问假设变量中的元素,如何在 python 中执行此操作?我可以访问大部分变量。下面是生成的 swig 代码...

class playerc_localize(_object):
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, playerc_localize, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, playerc_localize, name)
    __repr__ = _swig_repr
    __swig_setmethods__["info"] = _playerc.playerc_localize_info_set
    __swig_getmethods__["info"] = _playerc.playerc_localize_info_get
    if _newclass:info = _swig_property(_playerc.playerc_localize_info_get, _playerc.playerc_localize_info_set)
    __swig_setmethods__["map_size_x"] = _playerc.playerc_localize_map_size_x_set
    __swig_getmethods__["map_size_x"] = _playerc.playerc_localize_map_size_x_get
    if _newclass:map_size_x = _swig_property(_playerc.playerc_localize_map_size_x_get, _playerc.playerc_localize_map_size_x_set)
    __swig_setmethods__["map_size_y"] = _playerc.playerc_localize_map_size_y_set
    __swig_getmethods__["map_size_y"] = _playerc.playerc_localize_map_size_y_get
    if _newclass:map_size_y = _swig_property(_playerc.playerc_localize_map_size_y_get, _playerc.playerc_localize_map_size_y_set)
    __swig_setmethods__["map_scale"] = _playerc.playerc_localize_map_scale_set
    __swig_getmethods__["map_scale"] = _playerc.playerc_localize_map_scale_get
    if _newclass:map_scale = _swig_property(_playerc.playerc_localize_map_scale_get, _playerc.playerc_localize_map_scale_set)
    __swig_setmethods__["map_tile_x"] = _playerc.playerc_localize_map_tile_x_set
    __swig_getmethods__["map_tile_x"] = _playerc.playerc_localize_map_tile_x_get
    if _newclass:map_tile_x = _swig_property(_playerc.playerc_localize_map_tile_x_get, _playerc.playerc_localize_map_tile_x_set)
    __swig_setmethods__["map_tile_y"] = _playerc.playerc_localize_map_tile_y_set
    __swig_getmethods__["map_tile_y"] = _playerc.playerc_localize_map_tile_y_get
    if _newclass:map_tile_y = _swig_property(_playerc.playerc_localize_map_tile_y_get, _playerc.playerc_localize_map_tile_y_set)
    __swig_setmethods__["map_cells"] = _playerc.playerc_localize_map_cells_set
    __swig_getmethods__["map_cells"] = _playerc.playerc_localize_map_cells_get
    if _newclass:map_cells = _swig_property(_playerc.playerc_localize_map_cells_get, _playerc.playerc_localize_map_cells_set)
    __swig_setmethods__["pending_count"] = _playerc.playerc_localize_pending_count_set
    __swig_getmethods__["pending_count"] = _playerc.playerc_localize_pending_count_get
    if _newclass:pending_count = _swig_property(_playerc.playerc_localize_pending_count_get, _playerc.playerc_localize_pending_count_set)
    __swig_setmethods__["pending_time"] = _playerc.playerc_localize_pending_time_set
    __swig_getmethods__["pending_time"] = _playerc.playerc_localize_pending_time_get
    if _newclass:pending_time = _swig_property(_playerc.playerc_localize_pending_time_get, _playerc.playerc_localize_pending_time_set)
    __swig_setmethods__["hypoth_count"] = _playerc.playerc_localize_hypoth_count_set
    __swig_getmethods__["hypoth_count"] = _playerc.playerc_localize_hypoth_count_get
    if _newclass:hypoth_count = _swig_property(_playerc.playerc_localize_hypoth_count_get, _playerc.playerc_localize_hypoth_count_set)
    __swig_setmethods__["hypoths"] = _playerc.playerc_localize_hypoths_set
    __swig_getmethods__["hypoths"] = _playerc.playerc_localize_hypoths_get
    if _newclass:hypoths = _swig_property(_playerc.playerc_localize_hypoths_get, _playerc.playerc_localize_hypoths_set)
    __swig_setmethods__["mean"] = _playerc.playerc_localize_mean_set
    __swig_getmethods__["mean"] = _playerc.playerc_localize_mean_get
    if _newclass:mean = _swig_property(_playerc.playerc_localize_mean_get, _playerc.playerc_localize_mean_set)
    __swig_setmethods__["variance"] = _playerc.playerc_localize_variance_set
    __swig_getmethods__["variance"] = _playerc.playerc_localize_variance_get
    if _newclass:variance = _swig_property(_playerc.playerc_localize_variance_get, _playerc.playerc_localize_variance_set)
    __swig_setmethods__["num_particles"] = _playerc.playerc_localize_num_particles_set
    __swig_getmethods__["num_particles"] = _playerc.playerc_localize_num_particles_get
    if _newclass:num_particles = _swig_property(_playerc.playerc_localize_num_particles_get, _playerc.playerc_localize_num_particles_set)
    __swig_setmethods__["particles"] = _playerc.playerc_localize_particles_set
    __swig_getmethods__["particles"] = _playerc.playerc_localize_particles_get
    if _newclass:particles = _swig_property(_playerc.playerc_localize_particles_get, _playerc.playerc_localize_particles_set)
    def __init__(self, *args): 
        this = _playerc.new_playerc_localize(*args)
        try: self.this.append(this)
        except: self.this = this
    def destroy(self): return _playerc.playerc_localize_destroy(self)
    def subscribe(self, *args): return _playerc.playerc_localize_subscribe(self, *args)
    def unsubscribe(self): return _playerc.playerc_localize_unsubscribe(self)
    def set_pose(self, *args): return _playerc.playerc_localize_set_pose(self, *args)
    def get_particles(self): return _playerc.playerc_localize_get_particles(self)
    __swig_destroy__ = _playerc.delete_playerc_localize
    __del__ = lambda self : None;
playerc_localize_swigregister = _playerc.playerc_localize_swigregister
playerc_localize_swigregister(playerc_localize)

一切都在 SWIG 中编译,但现在我的 python 代码给出了错误。我知道 alpha 行可能是错误的,但我得到两行相同的错误:

LOC = playerc_localize(CON, 0)
if LOC.subscribe(PLAYERC_OPEN_MODE) != 0:
   raise playerc_error_str()

CON.read()
# This should work right? If I omit the index,
# then I get the first value from the array.
print LOC.get_hypoth(0).alpha
print LOC.get_hypoth(1)

我在python中收到以下错误:

print LOC.get_hypoth(1).alpha
File "/usr/local/lib/python2.7/dist-packages/playerc.py", line 7413, in get_hypoth
return _playerc._playerc_localize_get_hypoth(self, index)
TypeError: in method '_playerc_localize_get_hypoth', argument 1 of type 'playerc_localize_t *'

第 II 部分 我遇到了另一个问题,我再次尝试访问一些值,但它不起作用,我不知道出了什么问题。我正在尝试访问规划器设备中的航点:

PLN = playerc_planner(CON, 0)
  if PLN.subscribe(PLAYERC_OPEN_MODE) != 0:
     raise playerc_error_str()
# saves the waypoints in PLN.waypoints
PLN.get_waypoints()
# gives: <Swig Object of type 'double (*)[3]' at 0x38105d0>
# if i try accessing members of it using (0) or [0] or something I get errors
print PLN.waypoints

现在相关文件和部分:在 playerc.py

class playerc_planner(_object):
...
__swig_setmethods__["waypoints"] = _playerc.playerc_planner_waypoints_set
    __swig_getmethods__["waypoints"] = _playerc.playerc_planner_waypoints_get
    if _newclass:waypoints = _swig_property(_playerc.playerc_planner_waypoints_get, _playerc.playerc_planner_waypoints_set)

playerc_wrap.i 中的部分:

%header
%{
    #define new_playerc_planner playerc_planner_create
    #define del_playerc_planner playerc_planner_destroy
    typedef playerc_planner_t playerc_planner;
%}

typedef struct
{
  playerc_device info;
  int path_valid;
  int path_done;
  double px, py, pa;
  double gx, gy, ga;
  double wx, wy, wa;
  int curr_waypoint;
  int waypoint_count;
  double (*waypoints)[3];
    %extend
    {
        playerc_planner (playerc_client *client, int index);
        void destroy(void);
        int subscribe (int access);
        int unsubscribe (void);
        int set_cmd_pose (double gx, double gy, double ga);
        int get_waypoints (void);
        int enable (int state);
    }
} playerc_planner;

以及 playerc_wrap.h 中的相关部分:

typedef struct
{
  playerc_device_t info;
  int path_valid;
  int path_done;
  double px, py, pa;
  double gx, gy, ga;
  double wx, wy, wa;
  int curr_waypoint;
  int waypoint_count;
  double (*waypoints)[3];
} playerc_planner_t;

PLAYERC_EXPORT playerc_planner_t *playerc_planner_create(playerc_client_t *client, int index);
PLAYERC_EXPORT void playerc_planner_destroy(playerc_planner_t *device);
PLAYERC_EXPORT int playerc_planner_subscribe(playerc_planner_t *device, int access);
PLAYERC_EXPORT int playerc_planner_unsubscribe(playerc_planner_t *device);
PLAYERC_EXPORT int playerc_planner_set_cmd_pose(playerc_planner_t *device,
                                  double gx, double gy, double ga);
PLAYERC_EXPORT int playerc_planner_get_waypoints(playerc_planner_t *device);

PLAYERC_EXPORT int playerc_planner_enable(playerc_planner_t *device, int state);

所以我再次迷失了如何访问这个 double(*)[3] 变量中的航点,我尝试了一些东西,但都无法在 SWIG 中编译。再次感谢!

4

1 回答 1

1

看起来那些动态大小的数组没有正确包装在 libcplayer 的 SWIG 接口文件中。访问器LOC.hypoths可能只会给你数组中的第一个元素,而不是其他任何元素。

我认为最简单的做法是将这样的内容添加到 playerc.i 并重新生成 SWIG 绑定:

%inline %{
  player_localize_hypoth_t *_playerc_localize_get_hypoth(playerc_localize *localize, int index)
  {
    return &(localize->hypoths[index]);
  }
%}

%extend playerc_localize {
  %pythoncode %{
    def get_hypoth(self, index):
        return _playerc._playerc_localize_get_hypoth(self, index)
  %}
}

然后您应该能够n使用LOC.get_hypoth(n).

参考:

笔记:

结构的名称playerc_localize不是因为脚本playerc_localize_t应用于接口文件的正则表达式。playerc_swig_parse.py

第二部分

一个类似的问题。同样,可能有一种更聪明的方法可以做到这一点,但是这种简单的方法既好又干净,没有必要尝试让它变得比现在更复杂:

%inline %{
  double _playerc_planner_get_waypoint_coord(playerc_planner *planner, int index, int coord)
  {
    return planner->waypoints[index][coord];
  }
%}

%extend playerc_planner {
  %pythoncode %{
    def get_waypoint(self, index):
        x = _playerc._playerc_planner_get_waypoint_coord(self, index, 0)
        y = _playerc._playerc_planner_get_waypoint_coord(self, index, 1)
        z = _playerc._playerc_planner_get_waypoint_coord(self, index, 2)
        return (x, y, z)
  %}
}

然后你应该能够n像这样在 Python 中访问航点编号:

(x, y, z) = PLN.get_waypoint(n)
于 2013-05-07T15:04:36.973 回答