Help us understand the problem. What is going on with this article?

ドローン画像取得 (Erle-Copter, ArduPilot)

環境

Linux Mint 18.1 serena

言語設定

Erle-Brain3.
export LC_ALL=C
vi ~/.bashrc
> export LC_ALL=C

コンパイラ

ホストPC.
sudo apt install g++

ArduCopter

ArduCopterビルド

ホストPC.
sudo pip install future
git clone https://github.com/ardupilot/ardupilot
cd ardupilot/
git submodule update --init

ArduCopter起動

ホストPC.
ssh erle@192.168.10.6
sudo ./arducopter -A tcp:192.168.10.6:5760

カメラ情報の取得

参考URL
http://zumashi.blogspot.jp/2016/12/ros-kinetic-usb-cam.html

raspicamのインストール

参考URL:https://www.hackster.io/LanderU/erle-brain-2-live-video-streaming-into-the-web-browser-b3733d
http://forum.erlerobotics.com/t/rosservice-call-camera-start-capture-not-working/2230/8
https://github.com/fpasteau/raspicam_node

Erle-Brain3.
sudo apt install -y ros-raspicam-erlerobotics

raspicamの実行

・自動的にroscoreとraspicamが起動するようになっているので停止する。
・ROSマスターの情報を記載する。

Erle-Brain3.
export ROS_MASTER_URI=http://192.168.10.6:11311
export ROS_HOSTNAME=192.168.10.6
sudo vi /opt/ros/kinetic/camera.sh
# rosrun raspicam raspicam_node _framerate:=25 _quality:=45
sudo vi /opt/ros/kinetic/setup-ros.sh
# roscore

・手動でROSを実行する。

Erle-Brain3.
roscore &
rosrun raspicam raspicam_node _framerate:=25 _quality:=45 _width:=640 _height:=480 &
rosservice call /camera/start_capture &

ROS経由でpublishされた画像を表示する。

ホストPC.
export ROS_MASTER_URI=http://192.168.10.6:11311
export ROS_HOSTNAME=192.168.10.6
rosrun image_view image_view image:=/camera/image _image_transport:=compressed

Screenshot at 2017-05-25 00-25-45.png

Webブラウザ上で表示する。

・下記コードをcameraWeb.pyとして保存。

cameraWeb.py
#!/usr/bin/env python
# Python libs
import sys, time
# numpy and scipy
import numpy as np
from scipy.ndimage import filters
# OpenCV
import cv2
# Ros libraries
import roslib
import rospy
# Ros Messages
from sensor_msgs.msg import CompressedImage
import string,cgi,time
from os import curdir, sep
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
from SocketServer import ThreadingMixIn
import cv
import re
from threading import Thread, Lock
VERBOSE=True
import copy
mutex = Lock()
topic_name = "/camera/image/compressed"
class web_video_server:
    def __init__(self):
        '''Initialize ros publisher, ros subscriber'''
        # subscribed Topic
        self.subscriber = rospy.Subscriber(topic_name,
            CompressedImage, self.callback,  queue_size = 1)
        if VERBOSE :
            print "subscribed to " + topic_name
    def getCompressedImage(self):
        mutex.acquire(1)
        result = copy.deepcopy(self.np_arr);
        mutex.release()
        return result;
    def callback(self, ros_data):
        '''Callback function of subscribed topic. '''
        mutex.acquire(1)
        self.np_arr = ros_data.data;
        mutex.release()
class MyHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        try:
            self.path=re.sub('[^.a-zA-Z0-9]', "",str(self.path))
            if self.path=="" or self.path==None or self.path[:1]==".":
                return
            if self.path.endswith(".html"):
                f = open(curdir + sep + self.path)
                self.send_response(200)
                self.send_header('Content-type',    'text/html')
                self.end_headers()
                self.wfile.write(f.read())
                f.close()
                return
            if self.path.endswith(".mjpeg"):
                self.send_response(200)
                self.wfile.write("Content-Type: multipart/x-mixed-replace; boundary=--aaboundary")
                self.wfile.write("\r\n\r\n")
                while 1:
                  JpegData=self.ic.getCompressedImage();                    
                  self.wfile.write("--aaboundary\r\n")
                  self.wfile.write("Content-Type: image/jpeg\r\n")
                  self.wfile.write("Content-length: "+str(len(JpegData))+"\r\n\r\n" )
                  self.wfile.write(JpegData)
                  self.wfile.write("\r\n\r\n\r\n")    
                  time.sleep(0.05)
                return
            if self.path.endswith("*.jpeg"):
                self.send_response(200)
                self.wfile.write("Content-Type: multipart/x-mixed-replace; boundary=--aaboundary")
                self.wfile.write("\r\n\r\n")
                JpegData=self.ic.getCompressedImage();
                self.wfile.write("--aaboundary\r\n")
                self.wfile.write("Content-Type: image/jpeg\r\n")
                self.wfile.write("Content-length: "+str(len(JpegData))+"\r\n\r\n" )
                self.wfile.write(JpegData)
                self.wfile.write("\r\n\r\n\r\n")
                return
            return
        except IOError:
            self.send_error(404,'File Not Found: %s' % self.path)
        except :
            pass
class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
    """Handle requests in a separate thread."""
def main_server(args, ic):
    try:
        MyHandler.ic = ic
        server = ThreadedHTTPServer(('0.0.0.0', 8080), MyHandler)
        print 'started httpserver...'
        server.serve_forever()
    except KeyboardInterrupt:
        print '^C received, shutting down server'
        server.socket.close()  
def main_ros(args):
    '''Initializes and cleanup ros node'''
    rospy.init_node('web_video_server', anonymous=False)
    print 'started ROS...'
    try:
        rospy.spin()
    except KeyboardInterrupt:
        print "Shutting down ROS Image feature detector module"
    cv2.destroyAllWindows()
if __name__ == '__main__':
    ic = web_video_server()
    t = Thread(target=main_server, args=(sys.argv, ic))
    t.start()
    main_ros(sys.argv)
Erle-Brain3.
python cameraWeb.py

・ホストPCで下記URLにアクセスし、動画が表示できていることを確認。
http://192.168.10.6:8080/video.mjpeg

無題.png

おまけ

QtCreaotorのインストール(ROSソース編集のため)

ホストPC.
cd ~/
wget http://download.qt.io/archive/qt/5.7/5.7.0/qt-opensource-linux-x64-5.7.0.run
chmod +x qt-opensource-linux-x64-5.7.0.run
./qt-opensource-linux-x64-5.7.0.run

ROS

  • ワークスペース作成
Erle-Brain3.
mkdir -p ~/catkin_ws/src
cd ~/catkin_ws/src
catkin_init_workspace
cd ../
catkin_make
  • パッケージの作成
ホストPC.
cd ~/catkin_ws/src
catkin_create_pkg comm_erle std_msgs roscpp
  • ビルド
ホストPC.
cd ~/catkin_ws
catkin_make

MAVROS

参考URL:MAVROSインストール手順

  • wstoolインストール
ホストPC.
sudo apt install python-wstool
  • ワークスペースの作成
ホストPC.
mkdir -p ~/catkin_ws/src
cd ~/catkin_ws
catkin init
wstool init src
  • MAVLink・MAVROSインストール
ホストPC.
rosinstall_generator --rosdistro kinetic mavlink | tee /tmp/mavros.rosinstall
rosinstall_generator --upstream mavros | tee -a /tmp/mavros.rosinstall
  • ワークスペースの作成&依存関係解消
ホストPC.
wstool merge -t src /tmp/mavros.rosinstall
wstool update -t src -j4
rosdep install --from-paths src --ignore-src --os=ubuntu:xenial -y
  • ビルド
ホストPC.
catkin build
  • パス読み込み
ホストPC.
source devel/setup.bash
  • ホストPCでMAVROS起動
ホストPC.
rosrun mavros mavros_node _fcu_url:=tcp://192.168.10.6:5760

opencvインストール

参考URL:https://help.ubuntu.com/community/OpenCV

自作ノードで表示

参考URL:http://forum.erlerobotics.com/t/how-to-subscribe-camera-image-compressed/2341/7

最後に

ドローンの急速な発展に比べて、ドキュメントが追い付いてないですね。
フォーラムに散見した情報をかき集めてなんとかカメラの表示ができました。
古い情報が放置されていたりするので、注意が必要です。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away