AutoCar

본문 바로가기
사이트 내 전체검색


AutoCar
AutoCar

6. 서비스를 활용한 모터 제어

페이지 정보

작성자 관리자 댓글 0건 조회 1,878회 작성일 21-01-14 21:01

본문

6. 서비스를 활용한 모터 제어

서비스를 활용하여 모터를 제어해 보도록 하겠습니다. 

서비스 서버 에서는 서비스를 등록하고 전달된 데이터에 따라 모터를 제어합니다. 

클라이언트는 등록되어 있는 서비스를 호출하여 모터를 전진 또는 후진 또는 정지하도록 명령을 제어합니다.


전진 이나 후진을 하게될 경우 속도데이터를 함께 전달하여 제어하도록 합니다. 

속도 데이터는 0~100 으로 100 일 경우 최대 속도, 0 일 경우 움직이지 않습니다.


'catkin_create_pkg' 명령을 활용하여 패키지를 생성합니다. 

생성되는 패키지에 rospy와 std_msgs 패키지를 포함하도록 합니다.


jklee@holdings:~/catkin_ws/src$ catkin_create_pkg motor_service rospy std_msgs

Created file motor_service/package.xml

Created file motor_service/CMakeLists.txt

Created folder motor_service/src

Successfully created files in /home/jklee/catkin_ws/src/motor_service. Please adjust the values in package.xml.

jklee@holdings:~/catkin_ws/src$ cd motor_service/

jklee@holdings:~/catkin_ws/src/motor_service$



srv 폴더를 생성하고 폴더 내부에 motor.srv 파일을 생성하고 내용을 편집합니다.


jklee@holdings:~/catkin_ws/src/motor_service$ mkdir srv

jklee@holdings:~/catkin_ws/src/motor_service$ vi srv/motor.srv 

int64 motor_ctl 

int64 speed

---

int64 result



motor.srv 파일에 작성한 내용은 총 3 개의 변수의 내용을 담고 있습니다. 

motor_ctl은 전진, 후진, 정지를 제어할 내용을 담고 speed 는 전진과 후진을 제어할 때 모터의 속도를 제어하는 변수입니다.

motor.srv 파일을 작성 완료하고 나서 모터 서비스를 등록할 서버 프로그램을 작성합니다.


jklee@holdings:~/catkin_ws/src/motor_service$ vi src/server.py

#!/usr/bin/env python3


from motor_service.srv import *

import rospy

from pop import Pilot


Car = Pilot.AutoCar()


def motor_control(msg):

if msg.motor_ctl == 1:

Car.forward(msg.speed)

elif msg.motor_ctl == 2:

Car.backward(msg.speed)

elif msg.motor_ctl == 3:

Car.stop()

return 0


def motor_server():

rospy.init_node('motor_server')

s = rospy.Service('motor',motor,motor_control)

rospy.spin()


if __name__=="__main__":

motor_server()


코드에서 사용할 rospy 와 앞서 작성한 motor.srv 를 import 합니다. 

이후 서비스 호출시 호출될 motor_control() 메소드를 작성합니다. 

motor_control() 메소드의 전달 인자 msg 에는 motor.srv 에 작성한 motor_ctl 와 speed 가 전달되는 형태입니다.

motor_ctl 에 따라 전진, 후진, 정지를 결정하고 speed 에 따라 속도를 제어합니다. 

메인 루프가 시작되면 motor_server 노드를 등록하고 motor 서비스를 등록합니다.


작성을 완료하고 rosrun 을 활용하여 실행시 실행될 수 있도록 실행권한을 부여합니다.


jklee@holdings:~/catkin_ws/src/motor_service$ chmod +x src/server.py 


컴파일을 위한 CMakeLists.txt 파일과 package.xml 파일을 수정합니다. 

CMakeLists.txt 에는 컴파일 옵션들을 지정합니다. 

기본적인 내용은 패키지 생성시 미리 작성되어 있습니다. 

서비스 등록을 위한 내용을 추가합니다.


jklee@holdings:~/catkin_ws/src/motor_service$ vi CMakeLists.txt


### 생략
find_package(catkin REQUIRED COMPONENTS
  rospy
  std_msgs
  message_generation
)
### 생략 
add_service_files(
   FILES
   motor.srv
)
### 생략
generate_messages(
   DEPENDENCIES
   std_msgs  # Or other packages containing msgs
)
### 생략

package.xml 파일에는 컴파일 할 때 참조하는 패키지나 실행할 때 참조하는 내용을 입력합니다. 
package.xml 도 CMakeLists.txt 파일과 마찬가지로 패키지 생성시 기본적인 내용은 작성되어 있는상태로 필요한 내용만 추가하거나 주석을 제거하면 됩니다.

jklee@holdings:~/catkin_ws/src/motor_service$ vi package.xml

<!-- 생략 -->
<build_depend>message_generation</build_depend>
<!-- 생략 -->
<exec_depend>message_runtime</exec_depend>
<!-- 생략 -->

컴파일 및 실행을 위한 파일 수정은 완료되었습니다. 
catkin_make 명령을 통해 컴파일을 실행합니다. 
컴파일이 완료되고 나면 완료된 내용을 현재 사용중인 쉘에 적용해야 합니다. 
쉘에 변경사항을 적용하지 않는다면 새로 작성한 패키지의 내용을 찾지 못하거나 등록한 서비스의 내용을 정상적으로 확인하지 못할 수 있습니다. 
변경사항은 ~/catkin_ws/devel 폴더에 파일로 존재합니다. 
현재 사용중인 쉘의 종류에 따라 적용이 될 수 있도록 파일이 구분되어 있습니다. 
현재 bash 를 사용중입니다. 따라서 setup.bash 파일을 source 명령을 통해 적용합니다.

jklee@holdings:~/catkin_ws/src/motor_service$ cd ~/catkin_ws
jklee@holdings:~/catkin_ws$ catkin_make
Base path: /home/jklee/catkin_ws
Source space: /home/jklee/catkin_ws/src
Build space: /home/jklee/catkin_ws/build
Devel space: /home/jklee/catkin_ws/devel
Install space: /home/jklee/catkin_ws/install
####
#### Running command: "cmake /home/jklee/catkin_ws/src -DCATKIN_DEVEL_PREFIX=/home/jklee/catkin_ws/devel -DCMAKE_INSTALL_PREFIX=/home/jklee/catkin_ws/install -G Unix Makefiles" in "/home/jklee/catkin_ws/build"
####
-- Using CATKIN_DEVEL_PREFIX: /home/jklee/catkin_ws/devel
-- Using CMAKE_PREFIX_PATH: /home/jklee/catkin_ws/devel;/opt/ros/melodic
-- This workspace overlays: /home/jklee/catkin_ws/devel;/opt/ros/melodic
-- Found PythonInterp: /usr/bin/python2 (found suitable version "2.7.17", minimum required is "2")
-- Using PYTHON_EXECUTABLE: /usr/bin/python2
-- Using Debian Python package layout
-- Using empy: /usr/bin/empy
-- Using CATKIN_ENABLE_TESTING: ON
-- Call enable_testing()
-- Using CATKIN_TEST_RESULTS_DIR: /home/jklee/catkin_ws/build/test_results
-- Found gtest sources under '/usr/src/googletest': gtests will be built
-- Found gmock sources under '/usr/src/googletest': gmock will be built
-- Found PythonInterp: /usr/bin/python2 (found version "2.7.17")
-- Using Python nosetests: /usr/bin/nosetests-2.7
-- catkin 0.7.28
-- BUILD_SHARED_LIBS is on
-- BUILD_SHARED_LIBS is on
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- ~~  traversing 2 packages in topological order:
-- ~~  - motor_service
-- ~~  - service_tutorial
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- +++ processing catkin package: 'motor_service'
-- ==> add_subdirectory(motor_service)
-- Using these message generators: gencpp;geneus;genlisp;gennodejs;genpy
-- motor_service: 0 messages, 1 services
-- +++ processing catkin package: 'service_tutorial'
-- ==> add_subdirectory(service_tutorial)
-- Using these message generators: gencpp;geneus;genlisp;gennodejs;genpy
-- service_tutorial: 0 messages, 1 services
-- Configuring done
-- Generating done
-- Build files have been written to: /home/jklee/catkin_ws/build
####
#### Running command: "make -j4 -l4" in "/home/jklee/catkin_ws/build"
####
Scanning dependencies of target std_msgs_generate_messages_py
Scanning dependencies of target _motor_service_generate_messages_check_deps_motor
Scanning dependencies of target std_msgs_generate_messages_lisp
Scanning dependencies of target std_msgs_generate_messages_eus
[  0%] Built target std_msgs_generate_messages_lisp
[  0%] Built target std_msgs_generate_messages_py
[  0%] Built target std_msgs_generate_messages_eus
Scanning dependencies of target std_msgs_generate_messages_cpp
Scanning dependencies of target std_msgs_generate_messages_nodejs
[  0%] Built target std_msgs_generate_messages_cpp
[  0%] Built target std_msgs_generate_messages_nodejs
[  0%] Built target _motor_service_generate_messages_check_deps_motor
Scanning dependencies of target motor_service_generate_messages_lisp
Scanning dependencies of target motor_service_generate_messages_eus
Scanning dependencies of target motor_service_generate_messages_py
[  7%] Generating Lisp code from motor_service/motor.srv
[ 14%] Generating Python code from SRV motor_service/motor
[ 21%] Generating EusLisp code from motor_service/motor.srv
[ 21%] Built target _service_tutorial_generate_messages_check_deps_AddInts
Scanning dependencies of target motor_service_generate_messages_cpp
[ 28%] Generating C++ code from motor_service/motor.srv
[ 28%] Built target motor_service_generate_messages_lisp
Scanning dependencies of target motor_service_generate_messages_nodejs
[ 35%] Generating Javascript code from motor_service/motor.srv
[ 42%] Generating EusLisp manifest code for motor_service
[ 50%] Generating Python srv __init__.py for motor_service
[ 50%] Built target motor_service_generate_messages_nodejs
[ 57%] Built target service_tutorial_generate_messages_lisp
[ 71%] Built target service_tutorial_generate_messages_eus
[ 78%] Built target service_tutorial_generate_messages_cpp
[ 78%] Built target motor_service_generate_messages_py
[ 85%] Built target service_tutorial_generate_messages_nodejs
[100%] Built target service_tutorial_generate_messages_py
[100%] Built target service_tutorial_generate_messages
[100%] Built target motor_service_generate_messages_cpp
[100%] Built target motor_service_generate_messages_eus
Scanning dependencies of target motor_service_generate_messages
[100%] Built target motor_service_generate_messages
jklee@holdings:~/catkin_ws$

jklee@holdings:~/catkin_ws$ source devel/setup.bash


이제 프로그램 실행을 위해 새로운 터미널에서 마스터노드를 실행합니다. 
마스터 노드 실행 명령은 roscore 입니다.

jklee@holdings:~$ roscore
... logging to /home/jklee/.ros/log/d9f02d94-56d5-11eb-be2e-000000000001/roslaunch-holdings-28558.log
Checking log directory for disk usage. This may take a while.
Press Ctrl-C to interrupt
Done checking log file disk usage. Usage is <1GB.

started roslaunch server http://localhost:43199/
ros_comm version 1.14.7


SUMMARY
========

PARAMETERS
 * /rosdistro: melodic
 * /rosversion: 1.14.7

NODES

auto-starting new master
process[master]: started with pid [28571]

setting /run_id to d9f02d94-56d5-11eb-be2e-000000000001
process[rosout-1]: started with pid [28585]
started core service [/rosout]

새로 작성한 노드는 마스터 노드가 실행되어 있지 않다면 정상적으로 실행되지 않습니다. 
마스터 노드 실행된 이후에 마스터노드가 실행되지 않은 새로운 터미널에서 rosrun 명령을 통해 컴파일한 패키지를 실행합니다.

jklee@holdings:~/catkin_ws$ rosrun motor_service server.py

패키지를 실행하고나면 터미널에는 별다른 메시지가 출력되지 않습니다.
아무것도 실행되고 있지 않은 터미널에서 rosservice list 명령을 이용하면 현재 ros 에서 활용 가능한 서비스의 목록이 출력됩니다. 
새로 작성한 motor 서비스가 동작중인 것을 확인할 수 있습니다.

root@holdings:~# rosservice list
/motor
/motor_server/get_loggers
/motor_server/set_logger_level
/rosout/get_loggers
/rosout/set_logger_level

작성한 서비스를 활용하고 이를 rosservice 명령을 활용하지 않고 프로그램을 통해 호출하고 반환된 값을 화면에 출력하도록 합니다. 
서버와 마찬가지로 src 폴더에 프로그램을 작성합니다.

jklee@holdings:~$ cd catkin_ws/src/motor_service/
jklee@holdings:~/catkin_ws/src/motor_service$ vi src/client.py

#!/usr/bin/env python3

import rospy
from motor_service.srv import *

def service_client(ctl, speed):
    rospy.wait_for_service('/motor')
    try:
        motor_control = rospy.ServiceProxy('/motor',motor)
        return motor_control(ctl,speed)
    except rospy.ServiceException as e:
        print("Service call failed : %s"%e)

while True:
    ctl = int(input("1:forward, 2:backward, 3:stop "))
    if ctl != 3 :
        speed = int(input("plz input speed 0 ~ 100 "))
    else:
        speed = 0
    service_client(ctl,speed)


모터 서비스 클라이언트는 프로그램을 실행하면 동작을 키보드로 입력하도록 작성되어 있습니다. 
먼저 전진, 후진, 정지를 선택하고 이에 따라 속도를 지정합니다.
만약 정지라면 속도는 지정하지 않도록 합니다. 
입력된 값을 기준으로 service_client() 메소드를 호출합니다. 
service_client() 에서는 마스터 노드에 등록되어 있는 서비스를 검색합니다. 
/motor 서비스가 등록되어 있지 않다면 대기하고 등록되어 있다면 서비스를 호출하여 모터 제어 명령을 전달합니다.
만약 서비스가 제대로 호출되지 않는다면 에러메시지를 화면에 출력합니다.

프로그램 작성이 완료되면 rosrun 명령을 통해 서비스 클라이언트를 실행합니다. 
클라이언트를 실행하면 모터 제어 입력을 받습니다. 
입력한 명령에 따라 모터가 동작하는 것을 확인할 수 있습니다.

jklee@holdings:~/catkin_ws/src/motor_service$ chmod +x src/client.py

jklee@holdings:~/catkin_ws/src/motor_service$ rosrun motor_service client.py
1:forward, 2:backward, 3:stop 1
plz input speed 0 ~ 100 50
1:forward, 2:backward, 3:stop

 

댓글목록

등록된 댓글이 없습니다.


개인정보취급방침 서비스이용약관 모바일 버전으로 보기 상단으로

TEL. 063-469-4551 FAX. 063-469-4560 전북 군산시 대학로 558
군산대학교 컴퓨터정보공학과

Copyright © www.leelab.co.kr. All rights reserved.