Phase 1 | ROS로 조명 및 공조 시스템 제어하기 |
ROS Service Server 생성
이전 포스팅에서 roslibjs를 활용해 웹에서 데이터를 요청하고 받는 서비스 클라이언트를 생성했습니다. 위 다이어그램의 녹색 부위는 모두 완료한 셈입니다. 이제 붉은 부분을 해야 합니다. ROS에서도 요청을 받고 처리한 후 웹에 응답해줄 서비스 서버를 만들어야 합니다. 이번에는 C++ 기반의 ROS서비스 서버를 생성해보겠습니다. 아래의 명령어를 통해 cranberry_topic 패키지를 생성합니다.
catkin_create_pkg cranberry_topic std_msg roscpp message_runtime
CMakeLists.txt, CommLight.srv , comm_light_server.cpp 3가지 파일을 순서대로 편집합니다.
# ~/catkin_ws/src/cranberry_topic/CMakeLists.txt
# Written 2020-10-09 by whiteknight
# https://whiteknight3672.tistory.com
cmake_minimum_required(VERSION 2.8.3)
project(cranberry_topic)
find_package(catkin REQUIRED COMPONENTS message_generation std_msgs roscpp)
add_service_files(FILES CommLight.srv)
generate_messages(DEPENDENCIES std_msgs)
catkin_package(
LIBRARIES cranberry_topic
CATKIN_DEPENDS std_msgs roscpp message_runtime)
include_directories(${catkin_INCLUDE_DIRS})
add_executable(comm_light_server src/comm_light_server.cpp)
add_dependencies(comm_light_server ${${PROJECT_NAME}_EXPORTED_TARGETS}
${catkin_EXPORTED_TARGETS})
target_link_libraries(comm_light_server ${catkin_LIBRARIES})
// ~/catkin_ws/src/cranberry_topic/srv/CommLight.srv
// Written 2020-10-09 by whiteknight
// https://whiteknight3672.tistory.com
int32 target //Request
int32 state //Request
---
int32 result //Response
// ~/catkin_ws/src/cranberry_topic/src/comm_light_server.cpp
// Written 2020-10-09 by whiteknight
// https://whiteknight3672.tistory.com
#include "ros/ros.h" // ROS 기본 헤더파일
#include "cranberry_topic/CommLight.h" // CommLight.srv 파일 헤더 (빌드 후 자동 생성됨)
int light[4] = {0,}; // 추후를 대비해 light 개수를 4개로 잡았습니다.
bool lightCallback(cranberry_topic::CommLight::Request &req, cranberry_topic::CommLight::Response &res){
ROS_INFO("target : %d", req.target);
ROS_INFO("state : %d", req.state);
light[req.target -1] = req.state; // 받은 req.target에 해당하는 req.state를 저장합니다.
res.result = light[req.target -1]; // 성공적으로 저장된 경우, 값을 반환합니다.
return true;
}
int main(int argc, char **argv) // 노드 메인 함수
{
ros::init(argc,argv,"comm_light"); // comm_light이름을 가진 node 생성
ros::NodeHandle nh;
ros::ServiceServer service = nh.advertiseService("comm_light", lightCallback); // comm_light 이름의 서비스와, 수행할 함수를 설정
ROS_INFO("Ready to Send Callback : CommLightServer."); // 콘솔에 표시
ros::spin(); // 값 대기
return 0;
}
모든 과정을 완료한 후 다음 명령을 통해 패키지를 생성합니다.
cd ~/cakin_ws && catkin_make
이렇게 첫 패키지를 만들었습니다. 어디에서도 패키지에 접근할 수 있도록 다음 명령을 통해 환경변수를 설정해주고 한번 실행해봅니다.
echo "source ~/catkin_ws/devel/setup.bash" >> ~/.bashrc
source ~/.bashrc
roscore
// Service 서버
rosrun cranberry_topic comm_light_server
// 웹소켓 서버
roslaunch rosbridge_server rosbridge_websocket.launch
// Django 웹서버
cd ~/catkin_ws/src/Cranberry/cranberry_web && source web-env/bin/activate && python manage.py runserver
위의 명령을 모두 각기 다른 터미널 프로세스 위에서 실행시키고, 127.0.0.1:8000을 통해 웹페이지에 접속해봅니다.
Done!
브라우저에서 light 카드에 해당하는 전등을 눌러보고, rosrun cranberry_topic comm_light_server 를 실행시킨 터미널에서 데이터를 잘 받고 잘 보내는지 변화를 확인해봅니다. 그게 잘 안된다면, 웹브라우저에서 F12를 눌러 개발자 도구에 진입한 다음, console 탭에서 문제를 확인해봅니다.
긴 글 읽어주셔서 감사합니다. 도움이 되셨다면 왼쪽 아래 좋아요와, 광고 클릭 부탁드립니다.
고마움을 표현하는 가장 쉬운 방법입니다.