22 Jan 2019
|
C++
Future에 Timeout 적용
future에 Timeout을 적용하는 예제입니다.
ROS 2.0 관련 코드라 직접적으로 동작은 되지 않겠지만, wait_until()
을 이용해서 특정 시간을 기다리는 점에서는 사용방법이 동일합니다.
thread t1([client]() {
while (true) {
auto a = 0;
auto b = 0;
cout << "Input two number: " << endl;
cin >> a >> b;
auto req = make_shared<Add::Request>();
req->a = a;
req->b = b;
auto tp = std::chrono::system_clock::now() + std::chrono::seconds(3);
auto request = client->async_send_request(req);
auto status = request.wait_until(tp);
if (status == future_status::ready) {
auto resp = request.get();
cout << "Sum : " << resp->sum << endl;
} else {
cout << "Timeout !!!" << endl;
}
}
});
21 Jan 2019
|
ROS
ROS 2.0 Crystal
버전이 새로 나왔습니다. 역시나 기존의 Ardent
나 Bouncy
버전 때와 설치 방법이 조금 다른데, 그래도 거의 Bouncy
때의 설치 과정과 유사합니다.
아래 포스팅은 Ubuntu 18.04 버전을 처음 설치했다고 가정하고(아무런 패키지가 설치되지 않은 상태), ROS 2.0 Crystal 버전을 설치하는 과정입니다.
Locale 설정
sudo locale-gen en_US en_US.UTF-8
sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8
export LANG=en_US.UTF-8
기본 패키지 설치 및 repo key 설치
sudo apt update && sudo apt install curl gnupg2 lsb-release
curl http://repo.ros2.org/repos.key | sudo apt-key add -
sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 0xB01FA116
sudo apt-get update
sudo apt-get install python3-vcstool
기본 컴포넌트들 설치
sudo apt update && sudo apt install -y \
build-essential \
cmake \
git \
python3-colcon-common-extensions \
python3-pip \
wget
sudo apt install -y libpython3-dev
python3 -m pip install -U \
argcomplete \
flake8 \
flake8-blind-except \
flake8-builtins \
flake8-class-newline \
flake8-comprehensions \
flake8-deprecated \
flake8-docstrings \
flake8-import-order \
flake8-quotes \
git+https://github.com/lark-parser/lark.git@0.7d \
pytest-repeat \
pytest-rerunfailures \
pytest \
pytest-cov \
pytest-runner \
setuptools
sudo apt install --no-install-recommends -y \
libasio-dev \
libtinyxml2-dev
ROS 2.0 바이너리 다운로드 및 설치
미리 빌드된 ROS 2.0 바이너리를 다운로드합니다.
그리고 아래 명령어로 압축해제를 합니다.
mkdir -p ~/ros2_install
cd ~/ros2_install
tar xf ~/Downloads/ros2-crystal-20190117-linux-bionic-amd64.tar.bz2
rosdep 설치 및 초기화
sudo apt install -y python-rosdep
sudo rosdep init
sudo rosdep fix-permissions
rosdep update
만약 중간에 catkin-pkg
버전 때문에 에러가 발생하면 아래 명령어를 이용해서 버전 업데이트를 해줍니다.
sudo apt-get update && sudo apt-get install --only-upgrade python-catkin-pkg
OpenSlice 및 RTI Connext
OpenSlice
와 RTI Connext
는 굳이 설치를 할 필요는 없습니다. (어차피 상용 License라 사용하기엔 애매합니다.)
여기서는 패스합니다.
설치 확인
창을 2개 열어서 다음 명령어가 잘 동작하는지 확인합니다.~~~~
. ~/ros2_install/ros2-linux/setup.bash
ros2 run demo_nodes_cpp talker
. ~/ros2_install/ros2-linux/setup.bash
ros2 run demo_nodes_cpp listener
21 Jan 2019
|
C++
C++ JsonCpp 사용하기
JsonCpp의 repository는 여기입니다.
Amalgamated source
JsonCpp는 Amalgamated source
이라는 기능을 제공합니다. 이 기능은 간단한 간단한 python
스크립트를 이용해서 몇 개의 헤더 파일과 소스 파일을 만들어서 다른 프로젝트에서 쉽게 사용할 수 있게 해주는 기능입니다. JsonCpp 소스 파일 전체를 참조하지 않고 몇 개의 파일 추가만으로 기능을 사용할 수 있기 때문에 사용성이 많이 간편해집니다.
보다 자세한 내용은 여기에서 확인할 수 있습니다.
명령어는 다음과 같습니다.
python amalgamate.py
이 명령어를 수행하면 해당 디렉토리에 dist
라는 디렉토리가 생성되며 그 안에
.
├── json
│ ├── json-forwards.h
│ └── json.h
└── jsoncpp.cpp
구조로 파일들이 생성됩니다. 이 파일들을 복사해서 사용하려는 프로젝트에 넣고 사용하면 됩니다.
CMakeLists.txt
사용하려는 프로젝트의 CMakeLists.txt
사용 예제는 다음과 같습니다.
cmake_minimum_required(VERSION 3.15)
project(JsonExample)
set(CMAKE_CXX_STANDARD 14)
add_executable(JsonExample main.cpp jsonCpp/jsoncpp.cpp jsonCpp/json/json.h jsonCpp/json/json-forwards.h)
Json 파싱 예제
#include <iostream>
#include <fstream>
#include "jsonCpp/json/json.h"
using namespace std;
int main() {
Json::Value root;
Json::CharReaderBuilder reader;
ifstream is("MoveToPoint.json", ifstream::binary);
auto bret = Json::parseFromStream(reader, is, &root, &errorMessage);
if (bret == false) {
cout << "Error to parse JSON file !!!" << endl;
}
cout << "root: " << root << endl;
cout << "root.size(): " << root.size() << endl;
cout << "name: " << root["name"] << endl;
auto nodeList = root["nodeList"];
cout << "nodeList.size(): " << nodeList.size() << endl;
int left = 0;
for(auto n : nodeList) {
cout<<"- node: " << n["className"] << endl;
cout<<"- id: " << n["id"] << endl;
left = n["left"].asInt();
cout<<"- left: " << left << endl;
cout<<"- paramList: " << n["paramList"] << endl;
}
return 0;
}
Json 생성 예제
Json::Value compInfo;
compInfo["category"] = it->second;
compInfo["className"] = classInfo.name();
compInfo["type"] = getType();
auto seq = 0;
for (auto it = iter.begin(); it != iter.end(); it++) {
Json::Value paramInfo;
paramInfo["seq"] = seq++;
paramInfo["type"] = getTypeFromKind(it->second->kind());
paramInfo["name"] = it->first;
compInfo["paramList"].append(paramInfo);
}
root["componentList"].append(compInfo);
auto result = root.toStyledString();
}
21 Jan 2019
|
C++
C++ DataType 출력하기
typeid 명령어 이용
리눅스에서 gcc 기반으로 실행했을 때 Windows에서 Visual Studio로 실행했을 때의 결과가 조금 다릅니다.
void test01() {
int a = 10;
double b = 10.0;
string c = "abc";
bool d = true;
cout << typeid(a).name() << ", " << typeid(b).name() << ", " << typeid(c).name() << ", " << typeid(d).name()
<< endl;
}
i, d, NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE, b
std::is_same 명령어 이용
template<typename T>
std::string getType(T) {
std::string type = "unknown";
if (std::is_same<T, int>::value) type = "int";
if (std::is_same<T, double>::value) type = "double";
if (std::is_same<T, float>::value) type = "float";
if (std::is_same<T, bool>::value) type = "bool";
if (std::is_same<T, string>::value) type = "string";
return type;
}
void test02() {
int a = 10;
double b = 10.0;
string c = "abc";
bool d = true;
cout << getType(a) << ", " << getType(b) << ", " << getType(c) << ", " << getType(d) << endl;
}
int, double, string, bool
11 Jan 2019
|
C++
std::vector와 std::array
std::array
는 C++11
에서 새로 추가된 컨테이너로 예전부터 사용해오던 std::vector
와 비슷하게 생각할 수 있지만 약간의 차이점이 있습니다.
둘의 차이는 다음과 같습니다.
차이점
항목 |
vector |
array |
방식 |
인덱스 기반이 아닌 순차 데이터 저장 컨테이너 |
인덱스 기반의 fixed-sized 의 데이터 저장 컨테이너 |
동적 크기 변경 |
가능 |
고정. 컴파일 시점에 크기 정해짐 |
메모리 |
조금 더 많이 사용 |
조금 더 적게 사용 |
데이터 접근 시간 |
조금 더 오래 걸림 |
조금 더 적게 걸림 |
vector
가 내부적으로는 인덱스 기반으로 이루어져 있지는 않지만, 인덱스를 별도로 구성해서 제공하기 때문에, 인덱스를 이용한 접근이 가능합니다. 그리고 고정 크기가 아닌 가변 크기이기 때문에 인덱스를 별도로 동적으로 생성하기 때문에 array
보다는 성능이 조금 더 안 좋습니다. (물론, 대부분의 경우에는 큰 차이가 나지는 않습니다.)
vector
에서 특정 요소에 인덱스를 이용해서 접근할 때 [ ]
또는 at()
함수를 이용해서 접근할 수 있습니다.
데이터 접근시에는 항상 at()
함수를 이용하는 것이 좋습니다. 만약 인덱스 범위를 벗어날 경우 at()
함수는 out_of_range
예외를
발생시켜 예외 처리를 가능하게 하지만, [ ]
는 오류 없이 지나가서 오동작을 발생시켜 디버깅이 더 어렵게 만듭니다.