I'm trying to model a simple helicopter transform with a spinning rotor in RVIZ. I would prefer it to be timestamped into a single topic.

I've been working through the Odom and TimeTF examples in rosserial. I have a base_link that I would like to remain fixed in position but rotate on XYZ with data from an IMU (as the body of a helicopter in flight would behave).

I then have an odom that is translated a fixed, Z distance away that I would like to rotate about Z only, and be fixed to the rotation of base_link (as the spinning rotor on a helicopter would behave).

I have all the arduino code for the IMU and rotation/encoder done. I just can't seem to figure out how to do the above ROS part. The farthest I can get is to have a fixed base_link, + odom transform translated some distance from the body of the helicopter and have the rotor spin using a yaw quaternion (that takes angle position data from my encoder).


  • Is there a way to make the base link rotate about 3 values from my IMU (x,y,z)?
  • While simultaneously having the translated odom transform spinning?
  • Further, the above would constitute 4 different readings: (1) accel x, (2) accel y, (3) accel z, encoder position angle.
  • Can I also publish these all as individual values to a single topic?
  • Can I also publish an infinite amount of other values to this same topic as well under subheadings? Like temperature, gyro x, y, z, etc.?

I've included my arduino ros code progress below. Any help would be immensely appreciated! Thank you.

    // libraries
    #include <ros.h>
    #include <ros/time.h>
    #include <tf/transform_broadcaster.h>
    #include <tf/tf.h>
    ros::NodeHandle nh;
    // ros publisher instantiation for Odom & TF
    geometry_msgs::TransformStamped t;
    tf::TransformBroadcaster broadcaster;
    // ros chars
    char base_link[] = "/base_link";
    char rotor_odom[] = "/rotor_odom";

    float encoderAngle;
    void setup() {

       nh.initNode(); // ros node setup
       broadcaster.init(nh); // Odom & transform
    void rosLoop() {
        // tf odom->base_link:
          t.header.frame_id = base_link;
          t.child_frame_id = rotor_odom;
          t.transform.translation.x = 0;
          t.transform.translation.y = 0;
          t.transform.translation.z = 2;
          t.transform.rotation = tf::createQuaternionFromYaw(encoderAngle*3.141592/180);
          t.transform.rotation.x = 0.0;
          t.transform.rotation.y = 0.0;
          t.header.stamp = nh.now();
        // spinOnce
  • $\begingroup$ What do you mean by base link rotate about 3 values from my IMU (x,y,z)? ? And also, how are you updating the encoderAngle? Did you omit the rosserial part of the code? $\endgroup$
    – ignacio
    Nov 12, 2022 at 0:56
  • $\begingroup$ I was hoping that the initial transform could rotate using XYZ values from an IMU. encoderAngle comes from another sensor attached to the microcontroller. I omitted the sensor code because it is long and likely irrelevant. It's just a float. The code there is everything ROS related. I missed this one line in setup actually!: nh.advertise(encoderPublish); Otherwise that's everything there. Thanks for the response! $\endgroup$
    – ardoknow
    Nov 14, 2022 at 6:14


Your Answer

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

Browse other questions tagged or ask your own question.