diff --git a/Project.toml b/Project.toml index f7bdc2b..c8c019b 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "RosSockets" uuid = "f2b1035b-1fed-4502-a057-be66ed18c291" authors = ["Jacob Levy"] -version = "0.3.0" +version = "0.4.0" [deps] JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" diff --git a/README.md b/README.md index 0e33365..29a0125 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![RosSockets](https://github.com/CLeARoboticsLab/RosSockets.jl/actions/workflows/test.yml/badge.svg)](https://github.com/CLeARoboticsLab/RosSockets.jl/actions/workflows/test.yml) Tools for sending and receiving information from ROS via TCP that can be used to control robots. -This package is meant to communicate with the ROS nodes from [ros_sockets](https://github.com/CLeARoboticsLab/ros_sockets). +This package is meant to communicate with the ROS nodes from [ros_sockets](https://github.com/CLeARoboticsLab/ros_sockets), but also provides a framework for communication with TCP server in general. ## Installation @@ -83,6 +83,52 @@ When complete with tasks, be sure to close the connection: close_feedback_connection(feedback_connection) ``` +### General TCP Communication + +First, open a connection to the TCP server, setting setting `ip` and `port` to match that of the server: + +```jl +ip = "192.168.1.135" +port = 42423 +connection = open_connection(ip, port) +``` + +Send messages with `send`. Note: some TCP servers may be require the message be formatted a certain way (such as JSON), and may also require an end of line character, such as `\n`, to terminate the message. Here is an example of sending a JSON formatted message: + +```jl +import JSON + +# create a JSON formatted message with property name "action" and value "start_experiment" +start_cmd = JSON.json(Dict("action" => "start_experiment")) * "\n" + +# send the message +send(connection, start_cmd) +``` + +Send a message and wait for a response with `send_receive`. Note: some TCP servers may be require the message be formatted a certain way (such as JSON), and may also require an end of line character, such as `\n`, to terminate the message. This function blocks execution while waiting, up to the timeout duration provided. If the timeout duration elapses without the arrival of data, throws a `TimeoutError` exception. Note: the payload which is returned will be in a raw format. To convert to a string, use `String(payload)`. This string may further converted to other formats such as JSON. Here is an example of sending a JSON formatted message, receiving a response, and parsing the response. + +```jl +import JSON + +# create a JSON formatted message with property name "action" and value "get_time_elapsed" +get_time_cmd = JSON.json(Dict("action" => "get_time_elapsed")) * "\n" + +# send the message and wait for a response +payload = send_receive(connection, get_time_cmd) + +# convert the payload to a String, parse the String as a JSON, extract the data, +# and print it +data = JSON.parse(String(payload)) +elapsed_time = data["elapsed_time"] +println("Elapsed time: $(elapsed_time)") +``` + +When complete with tasks, be sure to close the connection: + +```jl +close_connection(connection) +``` + ## Acknowledgments The velocity control is heavily based on infrastructure from [@schmidma](https://github.com/schmidma) and [@lassepe](https://github.com/lassepe). diff --git a/examples/general_connection_example.jl b/examples/general_connection_example.jl index 4897457..bcbefb1 100644 --- a/examples/general_connection_example.jl +++ b/examples/general_connection_example.jl @@ -5,7 +5,7 @@ function test_time_server() ip = "192.168.1.135" # ip address of the host of the ROS node port = 42423 # port to connect on - # open a connection to the ROS node + # open a connection to a TCP server connection = open_connection(ip, port) # create command strings that are in the form of JSONs. These strings should @@ -15,10 +15,10 @@ function test_time_server() stop_cmd = JSON.json(Dict("action" => "stop_experiment")) * "\n" get_time_cmd = JSON.json(Dict("action" => "get_time_elapsed")) * "\n" - # send a command to the ROS node + # send a command to the TCP server send(connection, start_cmd) - # send a command and wait to receive a response from the ROS node + # send commands and wait to receive responses from the server for _ in 1:10 payload = send_receive(connection, get_time_cmd) data = JSON.parse(String(payload)) @@ -27,11 +27,11 @@ function test_time_server() sleep(0.5) end - # send another command to the ROS node + # send another command to the TCP server send(connection, stop_cmd) sleep(1.0) - # Close the connection to the ROS node. This should always be called when + # Close the connection to the TCP server. This should always be called when # complete with tasks to ensure graceful shutdown. close_connection(connection) end \ No newline at end of file