0
$\begingroup$

Rosanswers logo

I try to use tf::Quaternion and tf::createQuaternionMsgfromYaw in arduino

I have included ros.h and tf/transform_broadcaster.h

but when I build the code in arduino ide , it shows error:

> error: 'createQuaternionMsgFromYaw' is not a member of 'tf' error:
> error:'Quaternion' is not a member of 'tf'

I want to send transform on arduino, reference to official tutorial:Writing a tf broadcaster , using urdf with robot_state_publisher, and using time and tf on the arduino

I get data from robot, which stored in struct ArmData on arduino, including absolute positions and joint angles, and I want to publish joint_state and send transform to ros through rosserial_arduino.

when updating joint_state, I find that I cannot use resize() method, the way in tutorial using urdf with robot_state_publisher, since I do not install string lib on arudino ide. Is it neccesary to do so? Or, there is another way to substitute it using arduino code?

Is there any suggestion to code what I want to do on arduino? Thanks!

Here is part of my code with regard to update the joint_state and transform:

    geometry_msgs::TransformStamped ts;
    const double d2r=1000/57296; //turn degrees to radians

//update transform from odom to base_link
       ts.header.frame_id=odom;
       ts.child_frame_id=base_link;
       ts.transform.translation.x=0;
       ts.transform.translation.y=0;
       ts.transform.translation.z=.0115;
       //q.setRPY(0,0,ArmDataUnion.ArmData.Baseangle*d2r+d2r/2);
   //ts.transform.rotation.w=;
   ts.transform.rotation=tf::createQuaternionMsgFromYaw(ArmDataUnion.ArmData.Baseangle*d2r+d2r/2);
   ts.header.stamp=nh.now();
   
  //update joint_state
  joint_state.header.stamp=nh.now();
  //joint_state.name.resize(3);
  //joint_state.position.resize(3);
  joint_state.name[0]="base_joint";
  joint_state.position[0]=ArmDataUnion.ArmData.Baseangle*d2r;
  joint_state.name[1]="long_joint";
  joint_state.position[1]=ArmDataUnion.ArmData.LongArmangle*d2r;
  joint_state.name[2]="short_joint";
  joint_state.position[2]=ArmDataUnion.ArmData.ShortArmangle*d2r;


  //send the joint state to topic /joint_states
  joint_pub.publish(&joint_state);
  //send transform
  broadcaster.sendTransform(ts);

Edit1: Thanks for ahendrix's advice, I take a look at rosserialOverviewMessages

and modify my code according to what this tutorial does

But error occurs unfortunately.

    ros_dobot_arduino:93: error: 'jstate' does not name a type
 jstate.name=name;
 ^
ros_dobot_arduino:95: error: 'jstate' does not name a type
 jstate.name_length=3;
 ^
exit status 1
'jstate' does not name`enter code here` a type

It seems like sensor_msgs::JointState object does not have the methods which tutorial shows?

Edit2

#include <ros.h>
#include <sensor_msgs/JointState.h>
#include <ros/time.h>
#include <tf/tf.h>
#include <tf/transform_broadcaster.h>
#include <pt.h>   // include protothread library

The above are what I have included in Arduino code

Edit3

I have founded where the problem was.

It was because I assign value to rosserial msg before setup() function, which means the nodehandle has not yet been initialized!

I think, due to this, rosserial msg can not be used, right? If so, I want to know why needs a nodehandle, I just assgin a value to msg object?

At first, I want to pre-assign value to some msg because joint name did not change over time. So, I wrongly add this before setup() and right after declare sensor_msgs::JointState jstate

//assign the arrays to the message
jstate.name=jName;
//setting the length
jstate.name_length=3;

Thus, the above code should be put into setup() block and after nodelhandle has been initialized.


Originally posted by shawnysh on ROS Answers with karma: 339 on 2017-01-07

Post score: 2


Original comments

Comment by Humpelstilzchen on 2017-01-09:
Please note that Atmel AVRs do not have a floating point unit. And doing 32/64 bit floating point operation on an 8 bit device without FPU is not recommended. I would send the Odometry as yaw only and do the conversion on the PC.

$\endgroup$

1 Answer 1

0
$\begingroup$

Rosanswers logo

rosserial_arduino is NOT a full-featured ROS installation, so there are many features that don't work for the Arduino, and many things that are different.

In general, tutorials that describe standard ROS features do not apply to the Arduino.

In particular, array messages are raw C arrays; not vectors. Have a look at the rosserial Messages description, which shows how to properly initialize a JointState message on the arduino.

I don't see it in the documentation, but I believe that in order to get tf::createQuaternionFromYaw, you need to #include <tf/tf.h>

Update

It looks like you've made progress. You don't show the includes that you're using, but since the compiler is complaining about jstate it seems like you haven't included the header for the joint state message either. You probably need #include <sensor_msgs/JointState.h>

Update2

You don't need to initialize your messages and your NodeHandle in a particular order, but the message initialization does need to happen inside a function. You can have variable declarations outside a function, but you can't have other statements outside of a function. (This is a general rule in C and C++; not specific to rosserial or Arduino)


Originally posted by ahendrix with karma: 47576 on 2017-01-07

This answer was ACCEPTED on the original site

Post score: 2


Original comments

Comment by shawnysh on 2017-01-08:
I used tf::createQuaternionMsgFromYaw because I saw it in tutorial for urdf and I checked it in tf namespace reference, I think this tf reference is for roscpp only instead of arduino, right?

Comment by shawnysh on 2017-01-08:
So, I should check it in rosserial API document, right? Thanks

Comment by ahendrix on 2017-01-08:
Yes; the tf namespace reference only applies to roscpp. Unfortunately I think the rosserial API docs are incomplete, and they haven't documented tf::createQuaternionMsgFromYaw, even though it exists in rosserial_arduino

Comment by shawnysh on 2017-01-08:
omg, not documented yet?

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.