ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
0

Timer gets stuck and std_srvs/Empty

asked 2022-10-04 16:24:56 -0500

ajc225 gravatar image

updated 2022-10-07 02:00:37 -0500

ravijoshi gravatar image

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.

  1. When I ask for the service type, it says it is turtle_interfaces/srv/Toggle instead of std_srvs/Empty
  2. When I call the service using this type, it gives me the following error :

    AttributeError: 'Toggle_Request' object has no attribute 'std_srvs'
    
  3. 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 ...
(more)
edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
1

answered 2022-10-08 17:23:25 -0500

marguedas gravatar image

You define the type of a service when you declare the service, in your code:

self.toggle = self.create_service(Toggle,"toggle", self.toggle_callback)

Here you specify the type is Toggle you imported from turtle_interfaces.srv. If you want to use Empty you should change the line to be

self.toggle = self.create_service(Empty,"toggle", self.toggle_callback)

But toggle is a more semantic and descriptive name so it may be good for you to keep using that

edit flag offensive delete link more

Question Tools

2 followers

Stats

Asked: 2022-10-04 16:24:56 -0500

Seen: 62 times

Last updated: Oct 08 '22