command
*terminal 1
roslaunch rplidar_ros rplidar_a1.launch
*terminal 2
roslaunch hector_slam_launch tutorial.launch
if you want save current map, command this
rosrun map_server map_saver -f ~/my_map
+) initialize server with public domain
ngrok http --subdomain=arto 5000
++) and launch this script
sudo python3 server_2.py
from flask import Flask, request, jsonify, send_file
import os
import subprocess
from PIL import Image
import atexit
import time
import io
from functools import wraps
app = Flask(__name__)
# API Key Authentication (For Enhanced Security)
API_KEY = '2mLYH5v9QCl96lvRDkMWNjLJEsx_523BzdqXvkj8QKAZCBBFJ' # Replace with a secure key in production
def require_api_key(f):
@wraps(f)
def decorated(*args, **kwargs):
if 'x-api-key' not in request.headers:
return jsonify({"error": "API 키가 필요합니다."}), 401
if request.headers['x-api-key'] != API_KEY:
return jsonify({"error": "유효하지 않은 API 키입니다."}), 403
return f(*args, **kwargs)
return decorated
# Function to Execute ROS Command
def execute_ros_command():
"""
Executes the ROS map_saver command in the background and waits for the .pgm file to be created.
"""
try:
# Execute the ROS command in a bash shell
command = "rosrun map_server map_saver -f ~/my_map"
process = subprocess.Popen(command, shell=True, executable='/bin/bash')
# Path to the generated .pgm file
pgm_path = '/home/jetson/my_map.pgm' # Update this path as needed
# Wait for the .pgm file to be created with a timeout
timeout = 60 # seconds
elapsed_time = 0
while not os.path.exists(pgm_path) and elapsed_time < timeout:
time.sleep(1)
elapsed_time += 1
if os.path.exists(pgm_path):
# Optionally, wait for the process to finish
process.wait(timeout=10)
return True
else:
print("맵 파일 생성 시간이 초과되었습니다.")
return False
except Exception as e:
print(f"명령 실행 중 오류 발생: {e}")
return False
# Route to Save Map and Convert to PNG
@app.route('/save_map', methods=['POST'])
@require_api_key
def save_map():
"""
Executes the ROS map_saver command and converts the resulting .pgm file to .png.
"""
data = request.get_json()
if data and data.get('command') == 'save_map':
if execute_ros_command():
pgm_path = '/home/jetson/my_map.pgm' # Update this path as needed
png_path = '/home/jetson/my_map.png' # Desired PNG path
try:
# Open the .pgm file and convert it to .png
with Image.open(pgm_path) as img:
img = img.convert('RGB') # Convert to RGB if necessary
img.save(png_path, 'PNG')
return jsonify({"status": "success", "message": "Map saved and converted to PNG"}), 200
except Exception as e:
print(f"PNG 변환 중 오류 발생: {e}")
return jsonify({"status": "error", "message": "맵을 PNG로 변환하는 데 실패했습니다."}), 500
else:
return jsonify({"status": "error", "message": "맵 저장 명령을 실행하지 못했습니다."}), 500
return jsonify({"status": "error", "message": "유효하지 않은 명령입니다."}), 400
# 홈 디렉토리에 있는 .pgm 파일을 PNG로 변환하여 전송하는 라우트
@app.route('/image')
def send_image():
# 홈 디렉토리에서 파일 경로 지정
file_path = '/home/jetson/my_map.pgm'
if not os.path.exists(file_path):
return jsonify({'error': 'Map file not found'}), 404
# .pgm 이미지를 열어서 PNG로 변환
try:
with Image.open(file_path) as img:
img = img.convert('RGB') # 필요에 따라 색상 모드 변환
img_io = io.BytesIO()
img.save(img_io, 'PNG')
img_io.seek(0)
return send_file(img_io, mimetype='image/png')
except Exception as e:
print(f"Error converting map image: {e}")
return jsonify({'error': 'Failed to process map image'}), 500
# 외부에서 업로드된 .png 파일을 바로 처리하는 라우트
@app.route('/picture', methods=['POST'])
def handle_uploaded_picture():
if 'image' not in request.files:
return jsonify({'error': '파일이 없습니다.'}), 400
file = request.files['image']
if file.filename == '':
return jsonify({'error': '파일명이 없습니다.'}), 400
if file and file.filename.lower().endswith('.png'):
# 파일을 업로드 폴더에 저장
filepath = os.path.join(app.config['UPLOAD_FOLDER'], file.filename)
file.save(filepath)
return jsonify({'message': '파일 업로드 성공', 'filename': file.filename}), 200
return jsonify({'error': '유효하지 않은 파일 형식입니다. .png 파일을 업로드하세요.'}), 400
# 업로드된 이미지를 가져오는 라우트 (Flutter 앱에서 호출)
@app.route('/uploads/<filename>')
def get_uploaded_picture(filename):
filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename)
if os.path.exists(filepath):
return send_file(filepath, mimetype='image/png')
else:
return jsonify({'error': '파일을 찾을 수 없습니다.'}), 404
# Run the Flask App
if __name__ == '__main__':
# Register a shutdown handler
atexit.register(lambda: print("Flask 서버가 종료됩니다."))
# Run the app on all interfaces, port 5000
app.run(host='0.0.0.0', port=5000)
+++)
ngrok http --url=arto.ngrok.io 5000











