Ask Your Question
0

RPI4 IMU ROS ERROR: 'required argument is not a float' when writing 'header: ....

asked 2021-05-11 08:58:56 -0500

AsafWeitzman gravatar image

updated 2021-05-11 21:38:13 -0500

jayess gravatar image

Hey guys,

My System RPI 4 Ubuntu 20.04 ROS1

I am trying to publish some data from my IMU sensor (adafruit_bno055) that connect to my rpi via i2c but I am geting some error

rospy.exceptions.ROSSerializationException: <class ‘struct.error’>: ‘required argument is not a float’ when writing 'header:

for some reason I can’t find the solution, I still new and trying to understand the basics of ros, can someone point to the problem?

Note: I am using adafruit_bno055 library and I took most of the code from this example

the sensor print the data correctly when I run this code, but I guess I am missing something when I trying to use ros and publishing the data

here is my code:

import time
import board
import busio
from std_msgs.msg import Header, Float32
import adafruit_bno055
import rospy
from sensor_msgs.msg import Imu, Temperature
from std_msgs.msg import Int16


i2c = busio.I2C(board.SCL, board.SDA)
sensor = adafruit_bno055.BNO055_I2C(i2c)

last_val = 0xFFFF

if __name__ == '__main__':

    rospy.init_node('imu_data_node', anonymous=False)
    imu_pub = rospy.Publisher("/output/imu_data", Imu, queue_size=10)
    imu_temperature_pub = rospy.Publisher("/output/imu_temperature_ata", Int16, queue_size=10)

    rate = rospy.Rate(1)

    def temperature():
        global last_val  # pylint: disable=global-statement
        result = sensor.temperature
        if abs(result - last_val) == 128:
            result = sensor.temperature
            if abs(result - last_val) == 128:
                return 0b00111111 & result
        last_val = result
        return result

    seq = 0
    while not rospy.is_shutdown():

        imu_msg = Imu()

        current_time = rospy.Time.now()

        h = rospy.Header()
        h.stamp = current_time
        h.frame_id = 'imu_link'  # @SA: tf_broadcaster.py
        h.seq = seq
        # increase sequence
        seq = seq + 1
        # add header to IMU message
        imu_msg.header = h

        # copied
        imu_msg.orientation_covariance[0] = -1
        imu_msg.angular_velocity_covariance[0] = -1
        imu_msg.linear_acceleration_covariance[0] = -1

        imu_msg.orientation.x = sensor.quaternion[0]
        imu_msg.orientation.y = sensor.quaternion[1]
        imu_msg.orientation.z = sensor.quaternion[2]
        imu_msg.orientation.w = sensor.quaternion[3]

        # This represents a vector in free space.
        imu_msg.angular_velocity.x = sensor.gyro[0]
        imu_msg.angular_velocity.y = sensor.gyro[1]
        imu_msg.angular_velocity.z = sensor.gyro[2]

        # This represents a vector in free space.
        imu_msg.linear_acceleration.x = sensor.linear_acceleration[0]
        imu_msg.linear_acceleration.y = sensor.linear_acceleration[1]
        imu_msg.linear_acceleration.z = sensor.linear_acceleration[2]

        imu_pub.publish(imu_msg)
        imu_temperature_pub.publish(temperature())

        rate.sleep()

Here is my error:

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "imu_imu2.py", line 77, in <module>
    imu_pub.publish(imu_msg)
  File "/opt/ros/noetic/lib/python3/dist-packages/rospy/topics.py", line 886, in publish
    raise ROSSerializationException(str(e))
**rospy.exceptions.ROSSerializationException: <class 'struct.error'>: 'required argument is not a float' when writing 'header:**
  seq: 1
  stamp:
    secs: 1620665981
    nsecs: 771872520
  frame_id: "imu_link"
orientation:
  x: None
  y: None
  z: None
  w: None
orientation_covariance: [-1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
angular_velocity:
  x: -0.002181661564992912
  y: 0.001090830782496456
  z: 0.0
angular_velocity_covariance: [-1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
linear_acceleration:
  x: None
  y: None
  z: None
linear_acceleration_covariance: [-1, 0.0, 0.0, 0.0 ...
(more)
edit retag flag offensive close merge delete

Comments

Instead of using a screenshot to display text, please copy and paste the text directly into your question (images can't have the text within them copy and pasted and can quite often be difficult to read)

jayess gravatar image jayess  ( 2021-05-11 21:40:41 -0500 )edit

2 Answers

Sort by » oldest newest most voted
0

answered 2021-05-12 01:09:54 -0500

abhishek47 gravatar image

updated 2021-05-12 01:17:06 -0500

The problem could be in this line: h = rospy.Header()

Header belongs to std_msgs, and it's already being imported in from std_msgs.msg import Header, Float32. Try this instead:

h = Header()
h.stamp = rospy.Time.now()

(check out the accepted answer to What is the proper way to create a Header with python?)

edit flag offensive delete link more
0

answered 2021-05-11 20:51:33 -0500

Spectre gravatar image

updated 2021-05-11 20:54:13 -0500

I'm more familiar with ROS2 than ROS1, but it could be the lines:

current_time = rospy.Time.now()
h.stamp = current_time

The stamp component of the Header message must be a Time message: std_msgs/Time

stamp being a time message is shown here: std_msgs/Header

Double-check the return-value of rospy.Time.now(). It might be giving you some python Time object that you need to convert to a Time message object.

I was getting a similar error with ROS2 and rclpy when publishing odometry information:

    # Somewhere in a callback function...

    current_time = self.get_clock().now()  # Here I grab the current time, rclpy function is slightly different from rospy

    q = Quaternion()
    q.x = 0.0
    q.y = 0.0
    q.z = sin(self.position_theta / 2)
    q.w = cos(self.position_theta / 2)

    t = TransformStamped()
    t.header.stamp = current_time.to_msg()  # Here the time is converted to a Time message when we set 'stamp'
    t.header.frame_id = self.odom_frame_id
    t.child_frame_id = self.base_frame_id
    t.transform.translation.x = self.position_x
    t.transform.translation.y = self.position_y
    t.transform.translation.z = 0.0
    t.transform.rotation = q
    self.transform_broadcaster.sendTransform(t)

The ROS2 rclpy Time objects have a Time.to_msg() function to handle this.

You will either need to separately create a Time message and do h.stamp = time_msg, or you will need to see if you can just do h.stamp = current_time.to_msg() or similar.

Good luck!

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2021-05-11 08:58:56 -0500

Seen: 88 times

Last updated: May 12 '21