Commit 7613fecc authored by Oleg Dzhimiev's avatar Oleg Dzhimiev

testing

parent c198abeb
...@@ -6,6 +6,25 @@ import rclpy ...@@ -6,6 +6,25 @@ import rclpy
from elphel_interfaces.srv import StrReqStrRes from elphel_interfaces.srv import StrReqStrRes
import ros2_config import ros2_config
import sys
import html
# etree
#a = '<document><cmd>&</cmd></document>'
#xml = ET.Element("document")
#ET.SubElement(xml, "cmd").text = "begin & end"
#a = ET.tostring(xml)
#print(a)
#e = ET.fromstring(a)
#print(e)
#print(html.escape(e.find("cmd").text))
#sys.exit()
rclpy.init() rclpy.init()
node = rclpy.create_node('some_client_node') node = rclpy.create_node('some_client_node')
...@@ -16,8 +35,33 @@ while not cli.wait_for_service(timeout_sec=1.0): ...@@ -16,8 +35,33 @@ while not cli.wait_for_service(timeout_sec=1.0):
print('Service is not available, waiting '+str(wcnt)+'...') print('Service is not available, waiting '+str(wcnt)+'...')
wcnt += 1 wcnt += 1
###############################################################################
print("TEST1")
req = StrReqStrRes.Request()
req.request = '''<document>
<cmd>state</cmd>
</document>
'''
cli.call(req)
cli.wait_for_future()
res = cli.response.response
node.get_logger().info("cmd response:")
node.get_logger().info("\n"+res)
###############################################################################
print("TEST2")
req = StrReqStrRes.Request() req = StrReqStrRes.Request()
req.request = "wget -qO- -o /dev/null 'http://localhost/parsedit.php?immediate&TRIG'" req.request = '''<document>
<cmd>wget -qO- -o /dev/null 'http://localhost/parsedit.php?immediate&amp;TRIG'</cmd>
</document>
'''
cli.call(req) cli.call(req)
cli.wait_for_future() cli.wait_for_future()
...@@ -25,7 +69,8 @@ cli.wait_for_future() ...@@ -25,7 +69,8 @@ cli.wait_for_future()
res = cli.response.response res = cli.response.response
node.get_logger().info("cmd response:") node.get_logger().info("cmd response:")
node.get_logger().info(res) node.get_logger().info("\n"+res)
###############################################################################
node.destroy_node() node.destroy_node()
rclpy.shutdown() rclpy.shutdown()
\ No newline at end of file
...@@ -5,9 +5,7 @@ import ros2_config ...@@ -5,9 +5,7 @@ import ros2_config
cfg = ros2_config.get() cfg = ros2_config.get()
print(cfg) if cfg['role']=='master':
if cfg['role']=='master':
subprocess.Popen(['python3','ros2_master.py']) subprocess.Popen(['python3','ros2_master.py'])
subprocess.Popen(['python3','ros2_slave.py']) subprocess.Popen(['python3','ros2_slave.py'])
...@@ -2,44 +2,81 @@ ...@@ -2,44 +2,81 @@
import asyncio import asyncio
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
import xml.dom.minidom as minidom
import rclpy import rclpy
from elphel_interfaces.srv import StrReqStrRes from elphel_interfaces.srv import StrReqStrRes
import ros2_config import ros2_config
import urllib.parse
import html
TIMEOUT = 5 TIMEOUT = 5
# async coroutine for cmdall_callback
async def pass_cmd(target,cmd): async def pass_cmd(target,cmd):
#node = rclpy.create_node(target+'_client') cli = node.create_client(StrReqStrRes,target+'/cmd')
slave = cfg['slaves'][target] # if n/a
cli = node.create_client(StrReqStrRes,slave+'/cmd') if not cli.wait_for_service(timeout_sec=1.0):
return "<response><node>"+target+"</node><state>dead</state></response>"
wcnt = 0
while not cli.wait_for_service(timeout_sec=1.0):
print('Service is not available, waiting '+str(wcnt)+'...')
wcnt += 1
if wcnt==TIMEOUT:
break
# if alive
req = StrReqStrRes.Request() req = StrReqStrRes.Request()
req.request = cmd req.request = '<request><cmd>'+cmd+'</cmd></request>'
cli.call(req) cli.call(req)
cli.wait_for_future() cli.wait_for_future()
cmdres = cli.response.response cmdres = cli.response.response
return cmdres return cmdres
def parse_command(string):
msg = {}
e = ET.fromstring(string)
tmp = e.find('cmd')
if tmp!=None:
# have to escape: &
msg['cmd'] = html.escape(tmp.text)
else:
msg['cmd'] = 'state'
tmp = e.findall('target')
if not tmp:
msg['targets'] = clients
return msg
# callback for broadcast commands # callback for broadcast commands
def cmd_callback(req,res): def cmd_callback(req,res):
cmd = req.request # default function
tasks = [pass_cmd(c,cmd) for c in clients] cmd_func = pass_cmd
print("The raw command is:")
print(req.request)
q = parse_command(req.request)
print("parsed command:")
print(q)
if q['cmd']=='state':
cmd_func = pass_cmd
#if q['cmd']=='status':
# cmd_func = cmd_get_status
tasks = [cmd_func(cfg['slaves'][c],q['cmd']) for c in q['targets']]
results = event_loop.run_until_complete(asyncio.gather(*tasks)) results = event_loop.run_until_complete(asyncio.gather(*tasks))
print("Printing results:")
print(results) print(results)
res.response = '\n'.join(results) res.response = '\n'.join(results)
...@@ -54,7 +91,6 @@ cfg = ros2_config.get() ...@@ -54,7 +91,6 @@ cfg = ros2_config.get()
nodename = cfg['self']+'_master' nodename = cfg['self']+'_master'
for k,v in cfg['slaves'].items(): for k,v in cfg['slaves'].items():
print(k+' '+v)
clients.append(k) clients.append(k)
rclpy.init() rclpy.init()
...@@ -62,7 +98,7 @@ node = rclpy.create_node(nodename) ...@@ -62,7 +98,7 @@ node = rclpy.create_node(nodename)
event_loop = asyncio.get_event_loop() event_loop = asyncio.get_event_loop()
print('Starting master services:') print('\nStarting master services:')
print(' '+nodename+'/cmd') print(' '+nodename+'/cmd')
s1 = node.create_service(StrReqStrRes, nodename+'/cmd', cmd_callback) s1 = node.create_service(StrReqStrRes, nodename+'/cmd', cmd_callback)
......
...@@ -9,16 +9,38 @@ import ros2_config ...@@ -9,16 +9,38 @@ import ros2_config
TIMEOUT = 5 TIMEOUT = 5
def parse_command(string):
msg = {}
e = ET.fromstring(string)
tmp = e.find('cmd');
if tmp!=None:
msg['cmd'] = tmp.text
else:
msg['cmd'] = 'state'
return msg
# slave callbacks # slave callbacks
def cmd_callback(req,res): def cmd_callback(req,res):
cmd = req.request
# call to localhost here, get response and send it back
try:
output = subprocess.check_output(cmd,shell=True)
except subprocess.CalledProcessError:
output = "<error>-1</error>"
res.response = '<cmd><node>'+nodename+'</node><status>'+str(output)+'</status></cmd>' q = parse_command(req.request)
print("parsed command by slave:")
print(q)
if q['cmd']=='state':
res.response = '<response><node>'+nodename+'</node><state>idle</state></response>'
else:
# call to localhost here, get response and send it back
try:
output = subprocess.check_output(q['cmd'],shell=True)
except subprocess.CalledProcessError:
output = "<error>CalledProcessError</error>".encode()
res.response = '<response><node>'+nodename+'</node><state>'+output.decode()+'</state></response>'
return res return res
...@@ -30,7 +52,7 @@ nodename = cfg['self'] ...@@ -30,7 +52,7 @@ nodename = cfg['self']
rclpy.init() rclpy.init()
node = rclpy.create_node(nodename) node = rclpy.create_node(nodename)
print('Starting slave services:') print('\nStarting slave services:')
print(' '+nodename+'/cmd') print(' '+nodename+'/cmd')
s = node.create_service(StrReqStrRes, nodename+'/cmd', cmd_callback) s = node.create_service(StrReqStrRes, nodename+'/cmd', cmd_callback)
...@@ -39,4 +61,27 @@ rclpy.spin(node) ...@@ -39,4 +61,27 @@ rclpy.spin(node)
# Destroy the node explicitly # Destroy the node explicitly
# (optional - Done automatically when node is garbage collected) # (optional - Done automatically when node is garbage collected)
node.destroy_node() node.destroy_node()
rclpy.shutdown() rclpy.shutdown()
\ No newline at end of file
#xml = ET.Element("response")
##ET.SubElement(doc, "field1", name="blah").text = "some value1"
##ET.SubElement(doc, "field2", name="asdfasd").text = "some vlaue2"
#for k,v in cfg['slaves'].items():
#xml_node = ET.SubElement(xml, "node")
#ET.SubElement(xml_node, "name").text = k
#ET.SubElement(xml_node, "id").text = v
#if v in nodelist:
#s = "online"
#else:
#s = "offline"
#ET.SubElement(xml_node, "status").text = s
#xml_str = ET.tostring(xml).decode()
#xml_str = minidom.parseString(xml_str).toprettyxml(indent=" ")
#return xml_str
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment