250 lines
6.8 KiB
C++
250 lines
6.8 KiB
C++
|
/*
|
||
|
* Copyright (C) 2012 Open Source Robotics Foundation
|
||
|
*
|
||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
* you may not use this file except in compliance with the License.
|
||
|
* You may obtain a copy of the License at
|
||
|
*
|
||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||
|
*
|
||
|
* Unless required by applicable law or agreed to in writing, software
|
||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
* See the License for the specific language governing permissions and
|
||
|
* limitations under the License.
|
||
|
*
|
||
|
*/
|
||
|
/* Desc: Position Interface for Player
|
||
|
* Author: Nate Koenig
|
||
|
* Date: 2 March 2006
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
@addtogroup player
|
||
|
@par Position2d Interface
|
||
|
- PLAYER_POSITION2D_CMD_VEL
|
||
|
- PLAYER_POSITION2D_REQ_SET_ODOM
|
||
|
- PLAYER_POSITION2D_REQ_MOTOR_POWER
|
||
|
*/
|
||
|
|
||
|
/* TODO
|
||
|
- PLAYER_POSITION2D_REQ_GET_GEOM
|
||
|
- PLAYER_POSITION2D_REQ_RESET_ODOM
|
||
|
*/
|
||
|
#include <math.h>
|
||
|
#include <iostream>
|
||
|
|
||
|
#include "gazebo/transport/transport.hh"
|
||
|
#include "gazebo/msgs/msgs.hh"
|
||
|
#include "gazebo/math/gzmath.hh"
|
||
|
#include "GazeboDriver.hh"
|
||
|
#include "Position2dInterface.hh"
|
||
|
|
||
|
//////////////////////////////////////////////////
|
||
|
// Constructor
|
||
|
Position2dInterface::Position2dInterface(player_devaddr_t _addr,
|
||
|
GazeboDriver *_driver, ConfigFile *_cf, int _section)
|
||
|
: GazeboInterface(_addr, _driver, _cf, _section)
|
||
|
{
|
||
|
this->datatime = -1;
|
||
|
this->node = gazebo::transport::NodePtr(new gazebo::transport::Node());
|
||
|
this->node->Init(this->worldName);
|
||
|
this->modelName = _cf->ReadString(_section, "model_name", "default");
|
||
|
|
||
|
this->velPub = this->node->Advertise<gazebo::msgs::Pose>(
|
||
|
std::string("~/") + this->modelName + "/vel_cmd");
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////
|
||
|
// Destructor
|
||
|
Position2dInterface::~Position2dInterface()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////
|
||
|
// Handle all messages. This is called from GazeboDriver
|
||
|
int Position2dInterface::ProcessMessage(QueuePointer &_respQueue,
|
||
|
player_msghdr_t *_hdr, void *_data)
|
||
|
{
|
||
|
int result = 0;
|
||
|
|
||
|
// COMMAND VELOCITY:
|
||
|
if (Message::MatchMessage(_hdr, PLAYER_MSGTYPE_CMD,
|
||
|
PLAYER_POSITION2D_CMD_VEL, this->device_addr))
|
||
|
{
|
||
|
player_position2d_cmd_vel_t *cmd;
|
||
|
cmd = static_cast<player_position2d_cmd_vel_t*>(_data);
|
||
|
|
||
|
gazebo::msgs::Pose msg;
|
||
|
gazebo::msgs::Set(msg.mutable_position(),
|
||
|
ignition::math::Vector3d(cmd->vel.px, cmd->vel.py, 0));
|
||
|
gazebo::msgs::Set(msg.mutable_orientation(),
|
||
|
ignition::math::Quaterniond(0, 0, -cmd->vel.pa));
|
||
|
this->velPub->Publish(msg);
|
||
|
|
||
|
result = 0;
|
||
|
}
|
||
|
|
||
|
// REQUEST SET ODOMETRY
|
||
|
else if (Message::MatchMessage(_hdr, PLAYER_MSGTYPE_REQ,
|
||
|
PLAYER_POSITION2D_REQ_SET_ODOM, this->device_addr))
|
||
|
{
|
||
|
if (_hdr->size != sizeof(player_position2d_set_odom_req_t))
|
||
|
{
|
||
|
PLAYER_WARN("Arg to odometry set requestes wrong size; ignoring");
|
||
|
result = -1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
/*
|
||
|
player_position2d_set_odom_req_t *odom =
|
||
|
(player_position2d_set_odom_req_t*)_data;
|
||
|
|
||
|
this->iface->data->pose.pos.x = odom->pose.px;
|
||
|
this->iface->data->pose.pos.y = odom->pose.py;
|
||
|
this->iface->data->pose.yaw = odom->pose.pa;
|
||
|
*/
|
||
|
|
||
|
this->driver->Publish(this->device_addr, _respQueue,
|
||
|
PLAYER_MSGTYPE_RESP_ACK, PLAYER_POSITION2D_REQ_SET_ODOM);
|
||
|
|
||
|
result = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// CMD Set Motor Power
|
||
|
else if (Message::MatchMessage(_hdr, PLAYER_MSGTYPE_CMD,
|
||
|
PLAYER_POSITION2D_REQ_MOTOR_POWER, this->device_addr))
|
||
|
{
|
||
|
// TODO
|
||
|
result = 0;
|
||
|
}
|
||
|
|
||
|
// REQUEST SET MOTOR POWER
|
||
|
else if (Message::MatchMessage(_hdr, PLAYER_MSGTYPE_REQ,
|
||
|
PLAYER_POSITION2D_REQ_MOTOR_POWER, this->device_addr))
|
||
|
{
|
||
|
if (_hdr->size != sizeof(player_position2d_power_config_t))
|
||
|
{
|
||
|
PLAYER_WARN("Arg to motor set requestes wrong size; ignoring");
|
||
|
result = -1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// player_position2d_power_config_t *power;
|
||
|
// power = (player_position2d_power_config_t*)_data;
|
||
|
// this->iface->data->cmdEnableMotors = power->state;
|
||
|
|
||
|
this->driver->Publish(this->device_addr, _respQueue,
|
||
|
PLAYER_MSGTYPE_RESP_ACK, PLAYER_POSITION2D_REQ_MOTOR_POWER);
|
||
|
|
||
|
result = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// REQUEST GET GEOMETRY
|
||
|
else if (Message::MatchMessage(_hdr, PLAYER_MSGTYPE_REQ,
|
||
|
PLAYER_POSITION2D_REQ_GET_GEOM, this->device_addr))
|
||
|
{
|
||
|
if (_hdr->size != 0)
|
||
|
{
|
||
|
PLAYER_WARN("Arg get robot geom is wrong size; ignoring");
|
||
|
result = -1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
player_position2d_geom_t geom;
|
||
|
|
||
|
// TODO: get correct dimensions; these are for the P2AT
|
||
|
geom.pose.px = 0;
|
||
|
geom.pose.py = 0;
|
||
|
geom.pose.pz = 0;
|
||
|
geom.pose.pyaw = 0;
|
||
|
geom.pose.ppitch = 0;
|
||
|
geom.pose.proll = 0;
|
||
|
geom.size.sw = 0.53;
|
||
|
geom.size.sl = 0.38;
|
||
|
geom.size.sh = 0.31;
|
||
|
|
||
|
this->driver->Publish(this->device_addr, _respQueue,
|
||
|
PLAYER_MSGTYPE_RESP_ACK,
|
||
|
PLAYER_POSITION2D_REQ_GET_GEOM,
|
||
|
&geom, sizeof(geom), NULL);
|
||
|
|
||
|
result = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// REQUEST RESET ODOMETRY
|
||
|
else if (Message::MatchMessage(_hdr, PLAYER_MSGTYPE_REQ,
|
||
|
PLAYER_POSITION2D_REQ_RESET_ODOM, this->device_addr))
|
||
|
{
|
||
|
if (_hdr->size != 0)
|
||
|
{
|
||
|
PLAYER_WARN("Arg reset position request is wrong size; ignoring");
|
||
|
result = -1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// TODO: Make this work!!
|
||
|
this->driver->Publish(this->device_addr, _respQueue,
|
||
|
PLAYER_MSGTYPE_RESP_ACK, PLAYER_POSITION2D_REQ_RESET_ODOM);
|
||
|
result = 0;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
result = -1;
|
||
|
}
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////
|
||
|
// Update this interface, publish new info. This is
|
||
|
// called from GazeboDriver::Update
|
||
|
void Position2dInterface::Update()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
|
||
|
//////////////////////////////////////////////////
|
||
|
void Position2dInterface::Subscribe()
|
||
|
{
|
||
|
this->poseSub = this->node->Subscribe("~/pose/info",
|
||
|
&Position2dInterface::OnPoseMsg, this);
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////
|
||
|
void Position2dInterface::Unsubscribe()
|
||
|
{
|
||
|
this->poseSub.reset();
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////
|
||
|
void Position2dInterface::OnPoseMsg(ConstPosesStampedPtr &_msg)
|
||
|
{
|
||
|
// Iterate through all the pose messages
|
||
|
for (int i = 0; i < _msg->pose_size(); ++i)
|
||
|
{
|
||
|
if (_msg->pose(i).name() != this->modelName)
|
||
|
continue;
|
||
|
|
||
|
player_position2d_data_t data;
|
||
|
memset(&data, 0, sizeof(data));
|
||
|
|
||
|
this->datatime = gazebo::msgs::Convert(_msg->time()).Double();
|
||
|
|
||
|
data.pos.px = _msg->pose(i).position().x();
|
||
|
data.pos.py = _msg->pose(i).position().y();
|
||
|
ignition::math::Quaterniond quat =
|
||
|
gazebo::msgs::ConvertIgn(_msg->pose(i).orientation());
|
||
|
data.pos.pa = quat.Yaw();
|
||
|
|
||
|
this->driver->Publish(this->device_addr,
|
||
|
PLAYER_MSGTYPE_DATA,
|
||
|
PLAYER_POSITION2D_DATA_STATE,
|
||
|
static_cast<void*>(&data), sizeof(data), &this->datatime);
|
||
|
}
|
||
|
}
|