Timer gets stuck and std_srvs/Empty
I am trying to set up a std_srvs/Empty.srv
service that toggles between states, but there are a couple problems happening when I try to call the service.
- When I ask for the service type, it says it is
turtle_interfaces/srv/Toggle
instead ofstd_srvs/Empty
When I call the service using this type, it gives me the following error :
AttributeError: 'Toggle_Request' object has no attribute 'std_srvs'
When I assume that the type is
std_srvs/Empty.srv
and call it with this type instead, I get stuck with the following message:waiting for service to become available...
Update
I figured out that it gets stuck waiting. For some reason, the timer is not being started. But I don't understand why or how that is happening. The turtle simulation window no longer pops up, but the run window continuously prints my messages.
Also, I still don't understand why the type prints out turtle_interfaces/srv/Toggle.srv
instead of std_srvs/Empty.srv
, but only runs when I call it with std_srvs/Empty.srv
. I am not sure what is going on I added my code below :
import rclpy
from std_srvs.srv import Empty
from enum import Enum, auto
from std_msgs.msg import String, Float32
from geometry_msgs.msg import Twist, Vector3
from turtle_interfaces.srv import Toggle, Waypoints
from math import pi
from random import uniform
from rclpy.node import Node
from turtlesim.srv import Spawn, Kill, TeleportAbsolute, SetPen
from turtlesim.msg import Pose
from rcl_interfaces.msg import ParameterDescriptor
class Waypoint(Node):
"""
Publishes movement geometry_msgs/Twist commands at a fixed rate
"""
def __init__(self):
super().__init__('waypoint')
self.state = State.STOPPED
self.wstate = WayState.SET
self.declare_parameter("frequency", 100.0, ParameterDescriptor(description="frequency of node"))
self.declare_parameter("tolerance", 0.05, ParameterDescriptor(description="threashhold that a turtle reaches waypoint"))
self.publisher_ = self.create_publisher(String, "/turtle1/cmd_vel", 10)
self.sub = self.create_subscription(String, "Pose", self.pose_callback,10)
self.load = self.create_service(Waypoints,"load",self.load_callback)
self.toggle = self.create_service(Toggle,"toggle", self.toggle_callback)
self.freq = self.get_parameter("frequency").get_parameter_value().double_value
self.tol = self.get_parameter("tolerance").get_parameter_value().double_value
timer_period = 1/self.freq
self.timer = self.create_timer(timer_period, self.timer_callback)
self.i = 1
def toggle_callback(self,request,response):
"""
Callback function for the toggle service
switches the state of the turtle from moving to stop
Returns:
Empty
"""
self.get_logger().info(request.std_srvs.srv.Empty_Request())
# The new state of turtle
if self.state == State.MOVING:
self.state = State.STOPPED
elif self.state == State.STOPPED:
self.state = State.MOVING
return std_srvs.srv.Empty_Response()
def timer_callback(self):
#state checking
if self.state == State.STOPPED:
msg = String()
if self.i==1:
msg.data = 'Stopping'
self.i= self.i+1
else:
msg.data = ''
#publish msg once
self.publisher_.publish(msg)
self.get_logger().info('%s' %msg.data)
elif self.state == State.MOVING:
msg = String()
msg.data = 'Issuing Command!'
self.publisher_.publish(msg)
self.get_logger().info('Issuing Command!')
self.i = 1
##path very simple path algroithm
# use twist to move to points
#call current location and , find distance between location and point,
#velocity ...