Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ROS service to set location state #218

Merged
merged 1 commit into from
Jul 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pyrobosim_msgs/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ set(msg_files

set(srv_files
"srv/RequestWorldState.srv"
"srv/SetLocationState.srv"
)

set(action_files
Expand Down
2 changes: 1 addition & 1 deletion pyrobosim_msgs/srv/RequestWorldState.srv
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@

# No request
---
# Response contains a world sttae
# Response contains a world state
WorldState state
10 changes: 10 additions & 0 deletions pyrobosim_msgs/srv/SetLocationState.srv
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# ROS service to set the state of a location

# Request
string location_name
bool open
bool lock

---
# Response
ExecutionResult result
75 changes: 69 additions & 6 deletions pyrobosim_ros/pyrobosim_ros/ros_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@
import time

from geometry_msgs.msg import Twist
from pyrobosim.core.hallway import Hallway
from pyrobosim_msgs.action import ExecuteTaskAction, ExecuteTaskPlan
from pyrobosim_msgs.msg import RobotState, LocationState, ObjectState
from pyrobosim_msgs.srv import RequestWorldState
from pyrobosim_msgs.msg import ExecutionResult, RobotState, LocationState, ObjectState
from pyrobosim_msgs.srv import RequestWorldState, SetLocationState
from .ros_conversions import (
execution_result_to_ros,
pose_from_ros,
Expand Down Expand Up @@ -97,14 +98,21 @@ def __init__(
callback_group=ReentrantCallbackGroup(),
)

# World state service server
# World state service servers
self.world_state_srv = self.create_service(
RequestWorldState,
"request_world_state",
self.world_state_callback,
callback_group=ReentrantCallbackGroup(),
)

self.set_location_state_srv = self.create_service(
SetLocationState,
"set_location_state",
self.set_location_state_callback,
callback_group=ReentrantCallbackGroup(),
)

# Initialize robot specific interface lists
self.robot_command_subs = []
self.robot_state_pubs = []
Expand Down Expand Up @@ -401,11 +409,11 @@ def world_state_callback(self, request, response):
Returns the world state as a response to a service request.

:param request: The service request.
:type request: :class:`pyrobosim_msgs.srv._request_world_state.RequestWorldState_Request`
:type request: :class:`pyrobosim_msgs.srv.RequestWorldState.Request`
:param response: The unmodified service response.
:type response: :class:`pyrobosim_msgs.srv._request_world_state.RequestWorldState_Response`
:type response: :class:`pyrobosim_msgs.srv.RequestWorldState.Response`
:return: The modified service response containing the world state.
:rtype: :class:`pyrobosim_msgs.srv._request_world_state.RequestWorldState_Response`
:rtype: :class:`pyrobosim_msgs.srv.RequestWorldState.Response`
"""
self.get_logger().info("Received world state request.")

Expand Down Expand Up @@ -433,6 +441,61 @@ def world_state_callback(self, request, response):

return response

def set_location_state_callback(self, request, response):
"""
Sets the state of a location in the world as a response to a service request.

:param request: The service request.
:type request: :class:`pyrobosim_msgs.srv.SetLocationState.Request`
:param response: The unmodified service response.
:type response: :class:`pyrobosim_msgs.srv.SetLocationState.Response`
:return: The modified service response containing result of setting the location state.
:rtype: :class:`pyrobosim_msgs.srv.RequestWorldState.Response`
"""
self.get_logger().info("Received location state setting request.")

# Check if the entity exists.
entity = self.world.get_entity_by_name(request.location_name)
if not entity:
message = f"No location matching query: {request.location_name}"
self.get_logger().warn(message)
response.result.status = ExecutionResult.INVALID_ACTION
response.result.message = message
return response

if isinstance(entity, Hallway):
# Try open or close the hallway if its status needs to be toggled.
if request.open != entity.is_open:
if request.open:
result = self.world.open_hallway(entity)
else:
result = self.world.close_hallway(entity)

if not result.is_success():
response.result = execution_result_to_ros(result)
return response

# Try lock or unlock the hallway if its status needs to be toggled
if request.lock != entity.is_locked:
if request.lock:
result = self.world.lock_hallway(entity)
else:
result = self.world.unlock_hallway(entity)

if not result.is_success():
response.result = execution_result_to_ros(result)
return response

response.result.status = ExecutionResult.SUCCESS
return response

# If no valid entity type is reached, we should fail here.
message = f"Cannot set state for {entity.name} since it is of type {type(entity).__name__}."
self.get_logger().warn(message)
response.result.status = ExecutionResult.INVALID_ACTION
response.result.message = message
return response


def update_world_from_state_msg(world, msg):
"""
Expand Down
Loading