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

Easiest way to implement HTTP server that can send ROS messages

asked 2016-05-16 10:22:51 -0600

biellls gravatar image

I have a web interface that sends http requests to a server. When this server receives a request it needs to send messages through a ROS topic. Since this server will be very simple I thought that the easiest way would be to use Flask to make a REST service, but ROS doesn't seem to play nice with Flask. This is the code I am trying to execute:

#!/usr/bin/env python

## RESTful server that controls robot arm

import rospy
from std_msgs.msg import String
from flask import Flask, jsonify, request, abort

app = Flask(__name__)
topic='mytopic'

def talker():
    rospy.loginfo('Starting talker')
    pub = rospy.Publisher(topic, String, queue_size=10)
    rospy.init_node('talker', anonymous=True)
    rospy.loginfo('Talker started')

@App.route('/actions/execute', methods=['GET'])
def get_execute():
    action = request.args.get('action')
    if not action:
        abort(400)
    return action

if __name__ == '__main__':
    talker()
    rospy.loginfo("Starting Flask server")
    app.run(debug=True)

If I comment out the line that calls talker() in main, the server starts correctly. If I execute it as shown however, I get the following:

[INFO] [WallTime: 1463411613.101553] Talker started
[INFO] [WallTime: 1463411613.102112] Starting Flask server
[INFO] [WallTime: 1463411613.576470] Talker started
[INFO] [WallTime: 1463411613.576941] Starting Flask server

And the Flask server never starts. I also can't kill the process with ctrl-c. Is there a way to make ROS work with Flask? And if there isn't, what is the easiest way to accomplish what I'm trying?

edit retag flag offensive close merge delete

Comments

I am currently working on the same concept, however am also having to success. I am not super familiar with Flask, however it seems that both Flask and Ros require threads for their nodes. Have you had any success after this post?

iarc_team_erau gravatar image iarc_team_erau  ( 2017-04-17 16:23:45 -0600 )edit

@iarc_team_erau as far as I know there is no way to use ROS in a python server. Look into rosbridge/roslibjs which let you do the same (it's what I ended up using https://github.com/biellls/arm_contro... )

biellls gravatar image biellls  ( 2017-04-18 05:09:10 -0600 )edit

3 Answers

Sort by ยป oldest newest most voted
5

answered 2018-12-05 02:52:40 -0600

Sean Walters gravatar image

I think it can be made to work with rospy and Flask - the example below runs.

#! /usr/bin/env python

import os
import rospy
import threading

from flask import Flask

from std_msgs.msg import UInt32

def ros_callback(msg):
    print(msg)

threading.Thread(target=lambda: rospy.init_node('example_node', disable_signals=True)).start()
rospy.Subscriber('/listener', UInt32, ros_callback)
pub = rospy.Publisher('/talker', UInt32, queue_size=10)

app = Flask(__name__)

@App.route('/')
def hello_world():
    msg = UInt32()
    msg.data = 1
    pub.publish(msg)

    return 'Hello, World!'

if __name__ == '__main__':
    app.run(host=os.environ['ROS_IP'], port=3000)
edit flag offensive delete link more

Comments

I can't get the subscriber to print the msg. Does the data not go to console?

Void gravatar image Void  ( 2020-06-07 14:00:45 -0600 )edit
1

answered 2020-07-10 11:40:34 -0600

stoddabr gravatar image

I realize that this thread is pretty old but I ran into the same use case and couldn't find any clear tutorials. I did find some working code; turns out the trick is to run ROS and Flask on different threads. That code has a lot of extra stuff going on so I distilled it down and put it into my own github repo. Here's the link, feel free to post any issues there: https://github.com/stoddabr/ros_flask

edit flag offensive delete link more
0

answered 2017-12-29 22:30:54 -0600

Will_Welker gravatar image

It seems that rosbridge_server is what you are looking for. http://wiki.ros.org/rosbridge_server

Rosbridge server is part of the rosbridge_suite of packages, providing a WebSocket transport layer. A WebSocket is a low-latency, bidirectional communication layer between clients (web browsers) and servers. By providing a WebSocket connection, rosbridge server allows webpages to talk ROS using the rosbridge protocol.

edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2016-05-16 10:22:51 -0600

Seen: 8,397 times

Last updated: May 16 '16