srv host and client programmed - v1
This commit is contained in:
parent
cded485150
commit
2d7675fc93
175
src/pubsub/pubsub/pubsub_library_v3.py
Normal file
175
src/pubsub/pubsub/pubsub_library_v3.py
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
#********************************************#
|
||||||
|
# Publisher/Subscriber Class Library
|
||||||
|
|
||||||
|
# Creted for:
|
||||||
|
# ROS2 Workshop 2020
|
||||||
|
# Roverentwicklung für Explorationsaufgaben
|
||||||
|
# Institute for Space Systems
|
||||||
|
# University of Stuttgart
|
||||||
|
|
||||||
|
# Created by Patrick Winterhalder
|
||||||
|
# IRS, University of Stuttgart
|
||||||
|
#********************************************#
|
||||||
|
|
||||||
|
import rclpy
|
||||||
|
from rclpy.node import Node
|
||||||
|
|
||||||
|
# How to use:
|
||||||
|
# from pubsub_library import MinimalPublisher
|
||||||
|
# from pubsub_library import MinimalSubscriber
|
||||||
|
# minimal_publisher = MinimalPublisher(NODE_NAME='minimal_pub', TOPIC_NAME='user_controller', MSG_TYPE=Usercontroller, MSG_PERIOD=0.5)
|
||||||
|
# minimal_subscriber = MinimalSubscriber(NODE_NAME='minimal_sub', TOPIC_NAME='epos_feedback', MSG_TYPE=Eposreturn)
|
||||||
|
# See --> talker.py, listener.py
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Definition of Parent Classes
|
||||||
|
#******************************************************************************#
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class MinimalPublisher(Node):
|
||||||
|
|
||||||
|
def __init__(self, NODE_NAME, TOPIC_NAME, MSG_TYPE, MSG_PERIOD):
|
||||||
|
self.NODE_NAME= NODE_NAME
|
||||||
|
self.TOPIC_NAME = TOPIC_NAME
|
||||||
|
self.CUSTOM_MSG = MSG_TYPE
|
||||||
|
self.timer_period = MSG_PERIOD # [seconds]
|
||||||
|
# Init above laying class Node
|
||||||
|
super().__init__(self.NODE_NAME)
|
||||||
|
print("\t- " + str(TOPIC_NAME) + "\n")
|
||||||
|
self.publisher_ = self.create_publisher(
|
||||||
|
self.CUSTOM_MSG,
|
||||||
|
self.TOPIC_NAME,
|
||||||
|
10)
|
||||||
|
self.new_msg = False
|
||||||
|
# Define Node Frequency, equivalent to ~rospy.rate()
|
||||||
|
self.timer = self.create_timer(self.timer_period, self.publisher_timer)
|
||||||
|
return
|
||||||
|
|
||||||
|
def publisher_timer(self):
|
||||||
|
if self.new_msg is True:
|
||||||
|
try:
|
||||||
|
#self.get_logger().info('Pub:')
|
||||||
|
self.publisher_.publish(self.msg)
|
||||||
|
self.new_msg = False
|
||||||
|
except TypeError:
|
||||||
|
print("[ERROR] Msg-Data-Types do not match")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Publish using Timer
|
||||||
|
def timer_publish(self, msg):
|
||||||
|
self.msg=msg
|
||||||
|
self.new_msg = True
|
||||||
|
return
|
||||||
|
|
||||||
|
# Publish directly without Timer
|
||||||
|
def direct_publish(self, msg):
|
||||||
|
try:
|
||||||
|
#self.get_logger().info('Pub:')
|
||||||
|
self.publisher_.publish(msg)
|
||||||
|
except TypeError:
|
||||||
|
print("[ERROR] Msg-Data-Types do not match")
|
||||||
|
return
|
||||||
|
|
||||||
|
#******************************************************************************#
|
||||||
|
|
||||||
|
|
||||||
|
class MinimalSubscriber(Node):
|
||||||
|
|
||||||
|
def __init__(self, NODE_NAME, TOPIC_NAME, MSG_TYPE, NUM_MSGS):
|
||||||
|
self.NODE_NAME= NODE_NAME
|
||||||
|
self.TOPIC_NAME = TOPIC_NAME
|
||||||
|
self.CUSTOM_MSG = MSG_TYPE
|
||||||
|
self.NUM_MSGS = NUM_MSGS
|
||||||
|
self.topic_received = False
|
||||||
|
# Init above laying class "Node"
|
||||||
|
super().__init__(self.NODE_NAME)
|
||||||
|
self.subscription = self.create_subscription(
|
||||||
|
self.CUSTOM_MSG, # Message Type
|
||||||
|
self.TOPIC_NAME, # Topic Name
|
||||||
|
self.listener_callback, # Callback Function
|
||||||
|
self.NUM_MSGS) # List of saved messages
|
||||||
|
self.subscription # prevent unused variable warning
|
||||||
|
return
|
||||||
|
|
||||||
|
def listener_callback(self, msg):
|
||||||
|
#self.get_logger().info('I heard: "%s"' % msg.data)
|
||||||
|
self.msg = msg
|
||||||
|
return
|
||||||
|
|
||||||
|
def return_msg(self):
|
||||||
|
return self.msg
|
||||||
|
|
||||||
|
|
||||||
|
#******************************************************************************#
|
||||||
|
|
||||||
|
|
||||||
|
class MinimalServiceProvider(Node):
|
||||||
|
def __init__(self, NODE_NAME, SRV_NAME, SRV_TYPE):
|
||||||
|
self.NODE_NAME = NODE_NAME
|
||||||
|
self.SRV_NAME = SRV_NAME
|
||||||
|
self.SRV_TYPE = SRV_TYPE
|
||||||
|
# Init above laying class "Node"
|
||||||
|
super().__init__(self.NODE_NAME)
|
||||||
|
self.srv_host = self.create_service(self.SRV_TYPE, self.SRV_NAME, self.service_callback)
|
||||||
|
|
||||||
|
def service_callback(self, request, response):
|
||||||
|
"""
|
||||||
|
* request: first half of srv-file
|
||||||
|
* response: second half of srv-file
|
||||||
|
|
||||||
|
access values using:
|
||||||
|
* request.<name>
|
||||||
|
* response.<name>
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Add callback code here:
|
||||||
|
# What does Service do?
|
||||||
|
# ....
|
||||||
|
|
||||||
|
|
||||||
|
#self.get_logger().info('Incoming request\na: %d b: %d c: %d' % (request.a, request.b, request.c))
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
#******************************************************************************#
|
||||||
|
|
||||||
|
|
||||||
|
class MinimalServiceClient(Node):
|
||||||
|
def __init__(self, NODE_NAME, SRV_NAME, SRV_TYPE):
|
||||||
|
self.NODE_NAME = NODE_NAME
|
||||||
|
self.SRV_NAME = SRV_NAME
|
||||||
|
self.SRV_TYPE = SRV_TYPE
|
||||||
|
# Init above laying class "Node"
|
||||||
|
super().__init__(self.NODE_NAME)
|
||||||
|
self.srv_client = self.create_client(self.SRV_TYPE, self.SRV_NAME)
|
||||||
|
while not self.srv_client.wait_for_service(timeout_sec=1.0):
|
||||||
|
self.get_logger().info('service not available, waiting again...')
|
||||||
|
self.request = self.SRV_TYPE.Request()
|
||||||
|
|
||||||
|
def send_request(self, request):
|
||||||
|
"""
|
||||||
|
Feed request of type "SRV_TYPE.Request()"
|
||||||
|
"""
|
||||||
|
self.request = request
|
||||||
|
self.future = self.srv_client.call_async(self.request)
|
||||||
|
|
||||||
|
def check_if_service_completed(self):
|
||||||
|
if self.future.done():
|
||||||
|
try:
|
||||||
|
response = self.future.result()
|
||||||
|
except Exception as e:
|
||||||
|
self.get_logger().info(
|
||||||
|
'Service call failed %r' % (e,))
|
||||||
|
else:
|
||||||
|
# Adapt to fit service type
|
||||||
|
#self.get_logger().info(
|
||||||
|
'Result of add_three_ints: for %d + %d + %d = %d' %
|
||||||
|
(minimal_client.req.a, minimal_client.req.b, minimal_client.req.c, response.sum))
|
||||||
|
return response
|
||||||
|
else:
|
||||||
|
return None
|
Loading…
Reference in New Issue
Block a user