Robotics StackExchange | Archived questions

Current Time since epoch too big to send as rospy.Time?

I created a server and client pair program. The client sends a request with a rospy.time object. I save the current time since epoch into seconds and nano seconds fields of the time object. When I send the object to the server with a serviceProxy object I get a serialization error saying something is too large. I am assuming it is the nano seconds field:

 genpy.message.SerializationError: <class 'struct.error'>: ''I' format requires 0 <= number <= 4294967295' when writing 'time_input: 
  secs: 1597463455
  nsecs: 1597463455981233686'

Based on the documentation secs/nsecs are signed 32-bit ints. Since nsecs is larger than a 32bit int can hold, is it just impossible to send the current time since epoch in a rospy.time object? Is there a way around this besides creating a completely new message type? I attached everything just in case.

Thanks!!

convertTime.srv file:

time time_input
---
string time_string
float32 time_secs

Client .py File:

#!/usr/bin/env python3
import rospy
import time
from practice.srv import convertTime, convertTimeRequest, convertTimeResponse

#Initiate node and serviceProxy
rospy.init_node('time_converter_client')
serviceProxy = rospy.ServiceProxy('convertTime',convertTime)
rospy.wait_for_service('convertTime')

#Create time object and fill with current time
timeObject = rospy.Time()
timeObject.nsecs = int(time.time_ns())
timeObject.secs = int(time.time())

#Send request and handle response
response = serviceProxy(convertTimeRequest(timeObject))
print("Server Response: ")
print(response)

Server.py File

#!/usr/bin/env python3
import rospy
import time
from practice.srv import convertTime, convertTimeRequest, convertTimeResponse

def convert(msg):
    #save the original seconds recieved in msg
    secs = msg.time_input.secs
    #convert seconds since epoch to a readable time
    string_time = time.ctime(secs)
    #return a convertTimeResponse object with its field data passed to it
    return convertTimeResponse(string_time,secs)


#Initiate node and Service
rospy.init_node('time_converter_service')
service = rospy.Service('convertTime',convertTime,convert)
rospy.spin()

Error Created:

~/workspace$ rosrun practice time_converter_client.py 
Service Started... 

Sent client: 
3194926910981233686
Traceback (most recent call last):
  File "/home/jose/workspace/devel/lib/python3/dist-packages/practice/srv/_convertTime.py", line 55, in serialize
    buff.write(_get_struct_2I().pack(_x.time_input.secs, _x.time_input.nsecs))
struct.error: 'I' format requires 0 <= number <= 4294967295

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/jose/workspace/src/practice/src/time_converter_client.py", line 42, in <module>
    response = serviceProxy(convertTimeRequest(timeObject))
  File "/opt/ros/noetic/lib/python3/dist-packages/rospy/impl/tcpros_service.py", line 442, in __call__
    return self.call(*args, **kwds)
  File "/opt/ros/noetic/lib/python3/dist-packages/rospy/impl/tcpros_service.py", line 519, in call
    transport.send_message(request, self.seq)
  File "/opt/ros/noetic/lib/python3/dist-packages/rospy/impl/tcpros_base.py", line 672, in send_message
    serialize_message(self.write_buff, seq, msg)
  File "/opt/ros/noetic/lib/python3/dist-packages/rospy/msg.py", line 152, in serialize_message
    msg.serialize(b)
  File "/home/jose/workspace/devel/lib/python3/dist-packages/practice/srv/_convertTime.py", line 56, in serialize
    except struct.error as se: self._check_types(struct.error("%s: '%s' when writing '%s'" % (type(se), str(se), str(locals().get('_x', self)))))
  File "/opt/ros/noetic/lib/python3/dist-packages/genpy/message.py", line 385, in _check_types
    raise SerializationError(str(exc))
genpy.message.SerializationError: <class 'struct.error'>: ''I' format requires 0 <= number <= 4294967295' when writing 'time_input: 
  secs: 1597463455
  nsecs: 1597463455981233686'

Asked by Jose Sepulveda on 2020-08-14 23:34:08 UTC

Comments

Answers

#Create time object and fill with current time
timeObject = rospy.Time()
timeObject.nsecs = int(time.time_ns())
timeObject.secs = int(time.time())

The problem is time.time_ns() is the total number of nanoseconds since the epoch. The nsecs field should only contain the number of nanoseconds since since the secs field, meaning the number in nsecs should always be less than the number of nanoseconds in a second: 1,000,000,000.

Use rospy.Time.now() to get the current time instead.

http://wiki.ros.org/rospy/Overview/Time#Getting_the_current_time

#Create time object and fill with current time
timeObject = rospy.Time.now()

Asked by sloretz on 2020-08-17 09:11:50 UTC

Comments