将来自一个主题的数据放入回调函数中的动态数组并进行一些计算
Put data from one topic into a dynamic array in the Callback function and do some calculation
我正在从 Leap Motion 传感器读取手的姿势,我想计算手在 X
方向上移动的速度(通过计算 derivativex = dx / dt
)。我的解决方案是将 100 个手势值放在一个数组中,并在新消息 (msg->palmpos.x
) 通过主题 leapmotion/data
.
到达回调函数时不断用新值更新此数组
我的问题是当我用 ROS_ERROR("Hello %f", "derivativex")
打印 derivativex = dx / dt
时,输出总是:0
我做错了什么? link 我的回调正在监听的主题。
我的回调函数:
#include "geometry_msgs/TwistStamped.h"
#include "jog_msgs/JogJoint.h"
#include "jog_msgs/leapros.h"
#include "ros/ros.h"
#include <ros/console.h>
#include <iostream>
#include <iomanip>
#include <array>
using namespace std;
namespace to_twist
{
class spaceNavToTwist
{
public:
spaceNavToTwist() : spinner_(1)
{
joy_sub_ = n_.subscribe("leapmotion/data", 1, &spaceNavToTwist::joyCallback, this);
// Changed "spacenav/joy" to topic "/leapmotion/data"
twist_pub_ = n_.advertise<geometry_msgs::TwistStamped>("jog_arm_server/delta_jog_cmds", 1);
joint_delta_pub_ = n_.advertise<jog_msgs::JogJoint>("jog_arm_server/joint_delta_jog_cmds", 1);
spinner_.start();
ros::waitForShutdown();
};
const int arraySize = 100;// constant variable can be used to specify array size
double vectorx[ arraySize ] = {};// initialize elements of array n to 0
int resolution = 10;
double derivativex = 0;
double dx = 0;
int dt = 0;
private:
ros::NodeHandle n_;
ros::Subscriber joy_sub_;
ros::Publisher twist_pub_, joint_delta_pub_;
ros::AsyncSpinner spinner_;
// Convert incoming joy commands to TwistStamped commands for jogging.
void joyCallback(const jog_msgs::leapros::ConstPtr& msg)
{
for ( int count = 0; count < arraySize; ++count ) {// store the values of poses
vectorx[ count ] = msg->palmpos.x;
if (count>resolution) {
dx = vectorx[ count-1 ] - vectorx[ count-(resolution-1) ];
dt = resolution;
derivativex = dx / dt;
ROS_ERROR("Hello %f", derivativex);
}
if (count == arraySize) {
count=0;
}
}
问题 1:日志函数 ROS_ERROR 被误用。您应该传递一个浮点数而不是一个字符串,否则,您将得到一个未定义的行为:
ROS_ERROR("Hello %f", derivativex); // <-- there is no double quotes.
问题2:由于for循环开头的赋值,X的导数始终为0:
for ( int count = 0; count < arraySize; ++count ) {// store the values of poses
//Could you please explain why the program needs this ???
vectorx[ count ] = msg->palmpos.x; // <-- every element in vectorx is set to this values (const in each function call).
if (count>resolution) {
dx = vectorx[ count-1 ] - vectorx[ count-(resolution-1) ]; // is the same as (msg->palmpos.x - msg->palmpos.x) --> 0
dt = resolution;
derivativex = dx / dt;
ROS_ERROR("Hello %f", derivativex);
}
if (count == arraySize) {
count = 0; //<-- never get here because of count is always lesser than arraySize
}
}
我猜您想将 msg->palmpos.x 附加到 vectorx ? vectorx应该用std::vector,会容易很多。
这是您程序的修改版本,使用 std::vector :
//add this to your file
#include <vector>
//Your program body ...
//...
//As we are using C++, try to use C++ facilities if possible.
//const int arraySize = 100;// constant variable can be used to specify array size
//double vectorx[ arraySize ] = {};// initialize elements of array n to 0
std::vector<double> vectorx;
int resolution = 10;
int max_vector_size = 100; //keep 100 elements in the vectorx.
//...
// Convert incoming joy commands to TwistStamped commands for jogging.
void joyCallback(const jog_msgs::leapros::ConstPtr& msg)
{
//store the x coordinate in the vectorx
vectorx.push_back( msg->palmpos.x );
if( vectorx.size() > resolution ){
int id_back = vectorx.size() - 1;
double dx = vectorx[id_back] - vectorx[ id_back - resolution ];
double dt = resolution;
derivativex = dx / dt;
ROS_ERROR("Hello %f", derivativex);
}
while(vectorx.size() > max_vector_size ) {
vectorx.erase( vectorx.begin() ); //remove the first element
}
}//eof joyCallback
我正在从 Leap Motion 传感器读取手的姿势,我想计算手在 X
方向上移动的速度(通过计算 derivativex = dx / dt
)。我的解决方案是将 100 个手势值放在一个数组中,并在新消息 (msg->palmpos.x
) 通过主题 leapmotion/data
.
我的问题是当我用 ROS_ERROR("Hello %f", "derivativex")
打印 derivativex = dx / dt
时,输出总是:0
我做错了什么? link 我的回调正在监听的主题。
我的回调函数:
#include "geometry_msgs/TwistStamped.h"
#include "jog_msgs/JogJoint.h"
#include "jog_msgs/leapros.h"
#include "ros/ros.h"
#include <ros/console.h>
#include <iostream>
#include <iomanip>
#include <array>
using namespace std;
namespace to_twist
{
class spaceNavToTwist
{
public:
spaceNavToTwist() : spinner_(1)
{
joy_sub_ = n_.subscribe("leapmotion/data", 1, &spaceNavToTwist::joyCallback, this);
// Changed "spacenav/joy" to topic "/leapmotion/data"
twist_pub_ = n_.advertise<geometry_msgs::TwistStamped>("jog_arm_server/delta_jog_cmds", 1);
joint_delta_pub_ = n_.advertise<jog_msgs::JogJoint>("jog_arm_server/joint_delta_jog_cmds", 1);
spinner_.start();
ros::waitForShutdown();
};
const int arraySize = 100;// constant variable can be used to specify array size
double vectorx[ arraySize ] = {};// initialize elements of array n to 0
int resolution = 10;
double derivativex = 0;
double dx = 0;
int dt = 0;
private:
ros::NodeHandle n_;
ros::Subscriber joy_sub_;
ros::Publisher twist_pub_, joint_delta_pub_;
ros::AsyncSpinner spinner_;
// Convert incoming joy commands to TwistStamped commands for jogging.
void joyCallback(const jog_msgs::leapros::ConstPtr& msg)
{
for ( int count = 0; count < arraySize; ++count ) {// store the values of poses
vectorx[ count ] = msg->palmpos.x;
if (count>resolution) {
dx = vectorx[ count-1 ] - vectorx[ count-(resolution-1) ];
dt = resolution;
derivativex = dx / dt;
ROS_ERROR("Hello %f", derivativex);
}
if (count == arraySize) {
count=0;
}
}
问题 1:日志函数 ROS_ERROR 被误用。您应该传递一个浮点数而不是一个字符串,否则,您将得到一个未定义的行为:
ROS_ERROR("Hello %f", derivativex); // <-- there is no double quotes.
问题2:由于for循环开头的赋值,X的导数始终为0:
for ( int count = 0; count < arraySize; ++count ) {// store the values of poses
//Could you please explain why the program needs this ???
vectorx[ count ] = msg->palmpos.x; // <-- every element in vectorx is set to this values (const in each function call).
if (count>resolution) {
dx = vectorx[ count-1 ] - vectorx[ count-(resolution-1) ]; // is the same as (msg->palmpos.x - msg->palmpos.x) --> 0
dt = resolution;
derivativex = dx / dt;
ROS_ERROR("Hello %f", derivativex);
}
if (count == arraySize) {
count = 0; //<-- never get here because of count is always lesser than arraySize
}
}
我猜您想将 msg->palmpos.x 附加到 vectorx ? vectorx应该用std::vector,会容易很多。
这是您程序的修改版本,使用 std::vector :
//add this to your file
#include <vector>
//Your program body ...
//...
//As we are using C++, try to use C++ facilities if possible.
//const int arraySize = 100;// constant variable can be used to specify array size
//double vectorx[ arraySize ] = {};// initialize elements of array n to 0
std::vector<double> vectorx;
int resolution = 10;
int max_vector_size = 100; //keep 100 elements in the vectorx.
//...
// Convert incoming joy commands to TwistStamped commands for jogging.
void joyCallback(const jog_msgs::leapros::ConstPtr& msg)
{
//store the x coordinate in the vectorx
vectorx.push_back( msg->palmpos.x );
if( vectorx.size() > resolution ){
int id_back = vectorx.size() - 1;
double dx = vectorx[id_back] - vectorx[ id_back - resolution ];
double dt = resolution;
derivativex = dx / dt;
ROS_ERROR("Hello %f", derivativex);
}
while(vectorx.size() > max_vector_size ) {
vectorx.erase( vectorx.begin() ); //remove the first element
}
}//eof joyCallback