<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>wish-j.log</title>
        <link>https://velog.io/</link>
        <description>성장지향형 자율주행 소프트웨어 개발자입니다. K-Digital-Training: 자율주행 데브코스 Planning &amp; Control 1기로 활동하고 있습니다. 본 블로그를 통해 배움기록을 실천하고 있습니다. #자율주행 #기계공학</description>
        <lastBuildDate>Mon, 21 Aug 2023 10:58:14 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>wish-j.log</title>
            <url>https://velog.velcdn.com/images/wish-j/profile/0c4bbae3-a1ba-432f-b112-0892f66c6351/image.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. wish-j.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/wish-j" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[ROS Transform 정의와 사용법]]></title>
            <link>https://velog.io/@wish-j/ROS-Transform-%EC%A0%95%EC%9D%98%EC%99%80-%EC%82%AC%EC%9A%A9%EB%B2%95</link>
            <guid>https://velog.io/@wish-j/ROS-Transform-%EC%A0%95%EC%9D%98%EC%99%80-%EC%82%AC%EC%9A%A9%EB%B2%95</guid>
            <pubDate>Mon, 21 Aug 2023 10:58:14 GMT</pubDate>
            <description><![CDATA[<p>ROS(로봇 운영체제)에서 sendTransform 함수는 로봇의 위치 및 자세 변환(Transform)을 표현하고, 이를 ROS 네트워크 상에서 다른 노드와 공유하기 위해 사용되는 함수입니다. 이 함수는 tf 라이브러리를 통해 제공되며, 로봇의 각 부분의 상대적인 위치와 자세를 다루는 데 도움이 됩니다.</p>
<p>sendTransform 함수를 사용하여 변환 정보를 보내기 위해서는 다음과 같은 단계를 따를 수 있습니다:</p>
<ol>
<li>ROS 네임스페이스 및 라이브러리 임포트:</li>
</ol>
<pre><code>import rospy
import tf</code></pre><ol start="2">
<li><p>ROS 노드 초기화:</p>
<pre><code>rospy.init_node(&#39;your_node_name&#39;)</code></pre></li>
<li><p>tf.TransformerROS 객체 생성:</p>
</li>
</ol>
<pre><code>broadcaster = tf.TransformBroadcaster()</code></pre><ol start="4">
<li>변환 정보를 설정하고 전송:</li>
</ol>
<pre><code>while not rospy.is_shutdown():
    # Set the translation (position) and rotation (quaternion) values
    translation = (x, y, z)
    rotation = (qx, qy, qz, qw)

    # Specify the time and frame IDs
    current_time = rospy.Time.now()
    parent_frame = &quot;parent_frame&quot;
    child_frame = &quot;child_frame&quot;

    # Send the transformation
    broadcaster.sendTransform(
        translation,
        rotation,
        current_time,
        child_frame,
        parent_frame
    )

    # Add a delay if needed
    rospy.sleep(0.1)  # Delay for 0.1 seconds</code></pre><p>위 코드에서 x, y, z는 로봇의 위치 좌표이고, qx, qy, qz, qw는 로봇의 자세를 나타내는 쿼터니언(Quaternion) 회전 값을 나타냅니다. parent_frame은 부모 프레임의 이름이며, child_frame은 자식 프레임의 이름입니다. 이러한 변환 정보가 지속적으로 업데이트되어 sendTransform 함수를 통해 브로드캐스팅됩니다.</p>
<p>이렇게 하면 다른 ROS 노드에서 tf 라이브러리를 사용하여 변환 정보를 수신하고, 다른 프레임 간의 관계를 효과적으로 추적할 수 있습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[UTM 가상환경에서 VSCode 사용하기 (ssh)]]></title>
            <link>https://velog.io/@wish-j/UTM-%EA%B0%80%EC%83%81%ED%99%98%EA%B2%BD%EC%97%90%EC%84%9C-VSCode-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0-ssh</link>
            <guid>https://velog.io/@wish-j/UTM-%EA%B0%80%EC%83%81%ED%99%98%EA%B2%BD%EC%97%90%EC%84%9C-VSCode-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0-ssh</guid>
            <pubDate>Sun, 25 Jun 2023 14:31:59 GMT</pubDate>
            <description><![CDATA[<p>M1 mac에서 Ubuntu 환경을 사용하기 위해 UTM의 가상환경을 생성했다.
가상환경의 Ubuntu에서 VSCode를 설치하는 것은 실패 했다.</p>
<p><img src="https://velog.velcdn.com/images/wish-j/post/b2e9d44f-877e-4a62-b305-ddb7aa03030e/image.png" alt=""></p>
<p>위 사진과 같이, M1(Apple sillcon) 칩을 지원하는 설치 파일은 macOS 운영체제에서만 동작한다.
Ubuntu 환경의 경우 x64, Arm32, Arm64 칩만 지원한다.</p>
<p>VSCode를 사용해 가상환경으로 만든 Ubuntu의 소스코드를 편집하고 싶은 상황에서 찾은 방법은 SSH를 통한 원격 통신 방법이다.</p>
<p><a href="https://velog.io/@zhy2on/Ubuntu-20.04-for-ARM-%EC%84%A4%EC%B9%98%ED%95%B4%EB%B3%B4%EA%B8%B0">도움이 된 글 - Ubuntu SSH 설정 및 VSCode SSH 연결</a>
<a href="https://shanepark.tistory.com/239">적용한 글 (1) - Ubuntu SSH 설정</a>
<a href="https://dev-taerin.tistory.com/16">적용한 글 (2) - VSCode SSH 연결</a></p>
<h2 id="vscode-ssh-설정">VSCode SSH 설정</h2>
<ol>
<li><p>Remote-SSH 확장 프로그램 설치
<img src="https://velog.velcdn.com/images/wish-j/post/3a0e3871-e54f-44cd-96fa-7309ec871282/image.png" alt=""></p>
</li>
<li><p>⇧+⌘+p 단축키 입력, &#39;Remote-SSH: Open SSH Configuration File&#39; 선택하여 config 파일 수정
<img src="https://velog.velcdn.com/images/wish-j/post/e02c0ad7-59c6-4dca-abf2-26a2e7a7b279/image.png" alt=""></p>
</li>
<li><p>config 파일에 아래 입력</p>
</li>
</ol>
<ul>
<li>Host [User]@[HostName]:[Port]</li>
<li>HostName : 내부 ip 주소</li>
<li>User : 사용자 이름</li>
<li>Port : 포트 번호 (default 22)
<img src="https://velog.velcdn.com/images/wish-j/post/4165b5ff-2f6a-4018-a641-26ec79976825/image.png" alt=""></li>
</ul>
<ol start="4">
<li><p>⇧+⌘+p 단축키 입력, &#39;Remote-SSH: Connect to Host&#39; 선택하여 SSH 연결
<img src="https://velog.velcdn.com/images/wish-j/post/08af733d-c521-4e84-a342-0e19068fdf6b/image.png" alt=""></p>
</li>
<li><p>연결을 위한 암호 등등 입력하고 나면 아래 사진과 같이 Ubuntu 환경의 파일 시스템의 폴더를 열고 편집할 수 있음
<img src="https://velog.velcdn.com/images/wish-j/post/16e719d1-6cd6-4f61-8394-e633c64b1be1/image.png" alt=""></p>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[Git - .gitignore로 불필요한 파일 업로드 제외하기]]></title>
            <link>https://velog.io/@wish-j/Git-.gitignore%EB%A1%9C-%EB%B6%88%ED%95%84%EC%9A%94%ED%95%9C-%ED%8C%8C%EC%9D%BC-%EC%97%85%EB%A1%9C%EB%93%9C-%EC%A0%9C%EC%99%B8%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@wish-j/Git-.gitignore%EB%A1%9C-%EB%B6%88%ED%95%84%EC%9A%94%ED%95%9C-%ED%8C%8C%EC%9D%BC-%EC%97%85%EB%A1%9C%EB%93%9C-%EC%A0%9C%EC%99%B8%ED%95%98%EA%B8%B0</guid>
            <pubDate>Sat, 03 Jun 2023 13:31:24 GMT</pubDate>
            <description><![CDATA[<p>git은 동료들과 프로젝트 코드를 공유하기 좋은 협업 툴이다.</p>
<p>나는 ros workspace 내에서 작업중인 package 폴더를 git에 업로드 하고자 한다.</p>
<p>먼저 원하는 폴더를 git 로컬 저장소(rocal repository)로 지정해야 한다.</p>
<p>나는 작업중인 ros_workspace/src 폴더로 이동 후, 아래 명령어를 사용해 로컬 저장소를 생성했다.</p>
<pre><code>git init</code></pre><p>git status는 저장소 내 파일의 상태를 표시하여 준다.</p>
<pre><code>git status</code></pre><p><img src="https://velog.velcdn.com/images/wish-j/post/22718331-7c32-4656-8b65-6075d344bb2e/image.png" alt="">
실행 결과 git add 명령어로 staging area에 올라가지 않은 폴더가 붉은 색으로 표기되어 있다.</p>
<p>그러가 나는 이 폴더 중 1개의 폴더를 제외하고 git에 업로드할 필요가 없다.
따라서 로컬 저장소 내에 불필요한 폴더를 git이 관리하지 않도록 .gitignore 파일을 사용할 것이다.</p>
<p>다름 명령어를 통해 .gitignore 파일을 생성한다.</p>
<pre><code>vi .gitignore</code></pre><p>그런 뒤 위 사진에 보이는 붉은 색 폴더 명들을 복사하여 아래와 같이 일에 붙여넣기 한다. (원하는 폴더 명 제외)
<img src="https://velog.velcdn.com/images/wish-j/post/0eda7c22-bf97-4146-abb8-d021ecf43cec/image.png" alt=""></p>
<p>파일을 저장 후 아래 명령어를 실행시키면 다음 이미지와 같이 불필요한 파일이 관리 대상에서 제거된 것을 확인할 수 있다.</p>
<pre><code>git status</code></pre><p><img src="https://velog.velcdn.com/images/wish-j/post/647a3031-b0b5-46ae-900c-ec55c7f102fd/image.png" alt=""></p>
<p>이렇게 .gitignore 파일을 작성하면 업로드할 파일을 일일이 명명하지 않아도 git add . 를 이용해 변경된 전체 파일을 추가할 수 있다.</p>
<pre><code>git add</code></pre><p><img src="https://velog.velcdn.com/images/wish-j/post/253a19a8-7353-4b3c-ae41-53aa5838f4ca/image.png" alt="관리 폴더만 add 된 모습"></p>
<p>gitignore 파일과 관련된 문법은 아래 글을 참고했다.</p>
<p><a href="https://programming119.tistory.com/105">[Git] .gitignore이란? / .gitignore 사용법 </a>
<a href="https://git-scm.com/docs/gitignore">https://git-scm.com/docs/gitignore</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[ROS package 의존성 추가]]></title>
            <link>https://velog.io/@wish-j/ROS-package-%EC%9D%98%EC%A1%B4%EC%84%B1-%EC%B6%94%EA%B0%80</link>
            <guid>https://velog.io/@wish-j/ROS-package-%EC%9D%98%EC%A1%B4%EC%84%B1-%EC%B6%94%EA%B0%80</guid>
            <pubDate>Thu, 04 May 2023 01:20:40 GMT</pubDate>
            <description><![CDATA[<h3 id="문제-정의">문제 정의</h3>
<ul>
<li>아래 코드로 패키지 생성 시 의존성을 추가한다.
<code>catkin_create_pkg {PKG_NAME} [의존성]</code></li>
<li>그런데 이미 생성된 패키지에 의존성을 추가하고 싶은 상황이다.</li>
</ul>
<h3 id="해결방법">해결방법</h3>
<p><a href="http://wiki.ros.org/ko/ROS/Tutorials/catkin/CreatingPackage">package.xml 사용자화</a>를 따르자.</p>
<ol>
<li><p>대상 패키지 경로로 이동하여 package.xml 파일을 편집한다.
<code>$ vi package.xml</code></p>
</li>
<li><p><code>&lt;buildtool_depend&gt;catkin&lt;/buildtool_depend&gt;</code> 아래에 다음 코드를 추가한다.</p>
<pre><code>&lt;build_depend&gt;{의존성}&lt;/build_depend&gt;

&lt;exec_depend&gt;{의존성}&lt;/exec_depend&gt;
</code></pre></li>
</ol>
<p>```</p>
<ol start="3">
<li><code>rospack depends1 {PKG_NAME}</code> 명령어를 사용해 패키지의 의존성이 추가되었는지 확인한다.</li>
</ol>
<p><img src="https://velog.velcdn.com/images/wish-j/post/aa6f3aea-dfa4-43b5-b72e-34af5c1041ed/image.png" alt=""></p>
<p>의존성 추가가 확인되었다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[ROS practice #2 turtlesim in package]]></title>
            <link>https://velog.io/@wish-j/ROS-practice-2-turtlesim-in-package</link>
            <guid>https://velog.io/@wish-j/ROS-practice-2-turtlesim-in-package</guid>
            <pubDate>Wed, 03 May 2023 08:25:59 GMT</pubDate>
            <description><![CDATA[<h1 id="package-create--run">Package create &amp; run</h1>
<pre><code class="language-c">// pakage create
$ cd ~/xycar_ws/src
$ catkin_create_pkg my_pkg1 std_msgs rospy
$ cm
$ cd ~/xycar_ws/src/my_pkg1/src

// src code create
$ vi pub.py // 코드 편집
$ chmod +x pub.py // 실행 권한 부여

// rosrun
$ roscore // termial1
$ rosrun turtlesim turtlesim_node // termial2
$ rosrun my_pkg1 pub.py // termial3</code></pre>
<h3 id="pubpy">pub.py</h3>
<p>목표: 터틀심을 8자로 주행시키는 토픽 발행
실행 결과:
<img src="https://velog.velcdn.com/images/wish-j/post/7a92ddc1-f171-43b2-bd99-e4267104faa4/image.png" alt=""></p>
<p>소스코드: </p>
<pre><code>#!/usr/bin/env python3

import rospy
from geometry_msgs.msg import Twist

rospy.init_node(&#39;my_node&#39;, anonymous=True)
pub = rospy.Publisher(&#39;/turtle1/cmd_vel&#39;, Twist, queue_size=10) # topic, msg type, size?

msg = Twist()
msg.linear.x = 2.0
msg.linear.y = 0.0
msg.linear.z = 0.0
msg.angular.x = 0.0
msg.angular.y = 0.0
msg.angular.z = 1.8


msg2 = Twist()
msg2.linear.x = 2.0
msg2.linear.y = 0.0
msg2.linear.z = 0.0
msg2.angular.x = 0.0
msg2.angular.y = 0.0
msg2.angular.z = -1.8

rate = rospy.Rate(1)

iter_num = 0
msg_case = True
while not rospy.is_shutdown():

    if iter_num % 4 == 0:
        msg_case = False if msg_case is True else True
        iter_num = 0

    if msg_case:
        pub.publish(msg)
        # rospy.loginfo(f&#39;True, iter Num : {iter_num}&#39;)
    else:
        pub.publish(msg2)
        # rospy.loginfo(&#39;False&#39;)

    rate.sleep()

    iter_num += 1</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[ROS install, workspace setup]]></title>
            <link>https://velog.io/@wish-j/ROS-install-workspace-setup</link>
            <guid>https://velog.io/@wish-j/ROS-install-workspace-setup</guid>
            <pubDate>Wed, 03 May 2023 08:02:43 GMT</pubDate>
            <description><![CDATA[<h1 id="install">Install</h1>
<ul>
<li>참고 링크: <a href="https://velog.io/@deep-of-machine/ROS-ROS1-%EC%84%A4%EC%B9%98-Ubuntu20.04-ROS-Noetic">https://velog.io/@deep-of-machine/ROS-ROS1-설치-Ubuntu20.04-ROS-Noetic</a><ol>
<li>ROS를 제공하는 software repository 등록 (apt/sources.list)
<code>$ sudo sh -c &#39;echo &quot;deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main&quot; &gt; /etc/apt/sources.list.d/ros-latest.list&#39;</code></li>
<li>apt-key 셋업
<code>$ sudo apt install curl</code>
<code>$ curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | sudo apt-key add -</code>
<code>$ sudo apt update</code></li>
<li>패키지 설치
<code>$ sudo apt install ros-noetic-desktop-full</code>
<code>$ sudo apt install python3-rosdep</code></li>
<li>rosdep 초기화
<code>$ sudo apt install python3-rosdep python3-rosinstall python3-rosinstall-generator python3-wstool build-essential</code></li>
<li>쉘 환경 설정
<code>$ echo &quot;source /opt/ros/noetic/setup.bash&quot; &gt;&gt; ~/.bashrc</code>
<code>$ source ~/.bashrc</code></li>
<li>설치 확인
<code>$ roscore</code></li>
</ol>
</li>
</ul>
<h1 id="workspcase">Workspcase</h1>
<p>ros에서 코딩을 하기 위해 workspace라는 공간이 필요하다.</p>
<h3 id="catkin_make">catkin_make</h3>
<p>새로운 소스코드, 패키지 등 수정이 발생하면 ros 시스템이 알도록 ROS 프로그래밍 작업과 관련있는 모든 것들을 깔끔하게 정리해서 <strong>최신 상태로 빌드(build) 작업을 수행한다.</strong></p>
<p><strong>workspace 생성 코드:</strong></p>
<pre><code class="language-c">// create workspace
$ cd     // home directory
$ mkdir xycar_ws     // workspace 폴더 생성  
$ cd xycar_ws     // workspace 폴더로 이동
$ mkdir src // 소스 폴더 생성
$ catkin_make     //패키지 생성 (build, devel, src 폴더 및 패키지 파일 생성)</code></pre>
<p><strong>생성된 폴더 구조:</strong></p>
<ul>
<li>home<ul>
<li>xycar_ws : workspace<ul>
<li>src : 소스코드</li>
<li>build : 빌드 파일</li>
<li>devel</li>
</ul>
</li>
</ul>
</li>
</ul>
<h1 id="setup">Setup</h1>
<p>참고 링크 : <a href="https://enssionaut.com/board_robotics/812">https://enssionaut.com/board_robotics/812</a></p>
<ol>
<li><p>.bashrc를 수정하여 source 명령어가 터미널을 켤 때마다 자동적으로 실행되도록 설정
<code>$ vi ~/.bashrc</code></p>
</li>
<li><p>bash file에 아래 코드를 추가하여 ros 명령어 단축어, 소스파일 경로, master(roscore)의 uri 주소 등록</p>
<pre><code>source ~/xycar_ws/devel/setup.bash
</code></pre></li>
</ol>
<p>export ROS_MASTER_URI=<a href="http://localhost:11311">http://localhost:11311</a> 
export ROS_HOSTNAME=localhost</p>
<p>alias cw=&#39;cd ~/xycar_ws&#39; 
alias cs=&#39;cd ~/xycar_ws/src&#39;
alias cm=&#39;cd ~/xycar_ws &amp;&amp; catkin_make&#39;  </p>
<pre><code>3. 편집한 .bashrc 파일을 시스템에 반영
`source .bashrc`
3. 환경변수 설정 값 확인
`printenv | grep ROS # ros 이름을 포함한 환경 변수 리스트 출력`

![](https://velog.velcdn.com/images/wish-j/post/d6442a04-4506-4c1a-9af7-e9d3597e05b8/image.png)

# Package

패키지: 개발된 소프트웨어를 논리적 묶음으로 만든 것
참고 링크: http://wiki.ros.org/ko/ROS/Tutorials/catkin/CreatingPackage

### catkin_create_pkg
패키지 생성 명령어
```c
// pakage create
$ cd ~/xycar_ws/src   // catkin 작업공간의 소스 폴더로 이동
$ catkin_create_pkg my_pkg1 std_msgs rospy
$ cm
$ cd ~/xycar_ws/src/my_pkg1/src</code></pre><h3 id="rospack">rospack</h3>
<p>패키지 관련 기능을 수행하는 명령어</p>
<table>
<thead>
<tr>
<th>명령어</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>rospack list</td>
<td>패키지 리스트 출력 <br> grep 으로 연계하여 원하는 키워드 포함 리스트의 경로 출력</td>
</tr>
<tr>
<td>rospack find</td>
<td>패키지가 존재하는 경로 출력</td>
</tr>
<tr>
<td>rospack depends[#n]</td>
<td>패키지가 의존하는 파일 리스트 출력 <br> # 숫자 1 입력 시 필터링됨</td>
</tr>
<tr>
<td>roscd</td>
<td>패키지가 존재하는 경로로 이동</td>
</tr>
</tbody></table>
]]></description>
        </item>
        <item>
            <title><![CDATA[ROS practice #1 turtlesim]]></title>
            <link>https://velog.io/@wish-j/ROS-practice-1</link>
            <guid>https://velog.io/@wish-j/ROS-practice-1</guid>
            <pubDate>Wed, 03 May 2023 06:58:45 GMT</pubDate>
            <description><![CDATA[<h3 id="ros-turtlesim-실습">ROS turtlesim 실습</h3>
<p>목표</p>
<ol>
<li>master 실행 확인</li>
<li>subscriber node 실행 확인</li>
<li>publisher node 실행 확인</li>
</ol>
<hr>
<h3 id="명령어">명령어</h3>
<p>패키지 노드 실행 
<code>$ rosrun &lt;패키지 명&gt; &lt;노드명&gt;</code></p>
<hr>
<p><strong>terminal 1: master 실행</strong>
<code>$ roscore</code></p>
<p><strong>terminal 2: 토픽을 받아서 거북이를 이동시킴</strong>
<code>$ rosrun turtlesim turtlesim_node</code></p>
<p><strong>terminal 3: 사용자의 입력(키보드 방향키)에 따른 토픽 발행</strong>
<code>$ rosrun turtlesim turtle_teleop_key</code></p>
<p>  실행 결과: TurtleSim이 키보드 방향키 입력에 따라 이동함
<img src="https://velog.velcdn.com/images/wish-j/post/908059b9-6343-4be9-a18f-f8e8b4d02e33/image.png" alt="실행결과"></p>
<p><strong>terminal 4: 상태 확인</strong></p>
<ul>
<li><p>node list 출력
<code>$ rosnode list</code>
/rosout
/teleop_turtle
/turtlesim</p>
</li>
<li><p>node 정보 출력
<code>$ rosnode info</code></p>
</li>
</ul>
<ul>
<li><p>node와 topic의 관계 graph 출력
<code>$ rqt_graph</code>
<img src="https://velog.velcdn.com/images/wish-j/post/c3a17766-8f35-47f8-8fe7-39b17fdff717/image.png" alt=""></p>
</li>
<li><p>publisher에서 발행한 topic list 확인
<code>$ rostopic list</code>
/rosout
/rosout_agg
/turtle1/cmd_vel
/turtle1/color_sensor
/turtle1/pose</p>
</li>
<li><p>특정 topic이 확인될 때 마다 message를 출력
<code>$ rostopic echo &lt;topic&gt;</code></p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[ROS 노드 통신 프로그래밍]]></title>
            <link>https://velog.io/@wish-j/ROS-%EB%85%B8%EB%93%9C-%ED%86%B5%EC%8B%A0-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D</link>
            <guid>https://velog.io/@wish-j/ROS-%EB%85%B8%EB%93%9C-%ED%86%B5%EC%8B%A0-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D</guid>
            <pubDate>Mon, 01 May 2023 12:38:42 GMT</pubDate>
            <description><![CDATA[<h2 id="노드간-통신-구성">노드간 통신 구성</h2>
<ul>
<li>Publisher<ul>
<li>topic 발행</li>
<li>node name = node1</li>
</ul>
</li>
<li>Subscriver<ul>
<li>topic 수신</li>
<li>node name = node2</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/wish-j/post/e37f33fd-7833-4918-8c0e-e0f11d3740be/image.png" alt=""></p>
<h2 id="11-통신">1:1 통신</h2>
<p>Pakage create &amp; run</p>
<pre><code class="language-c">// 패키지 생성
cd ~/xycar_ws/src
catkin_create_pkg &lt;msg_send&gt; [std_msgs] [rospy] # 패키기가 의존하고 있는 다른 패키지 나열
catkin_make

//src
cd src
vi student.py
vi teacher.py

// launch 
mkdir launch
cd launch
vi m_send.launch

// build
cm

//launch
roslaunch msg_send m_send.launch</code></pre>
<h1 id="다양한-통신-구성">다양한 통신 구성</h1>
<p><img src="https://velog.velcdn.com/images/wish-j/post/34746450-d43f-43ec-b6eb-7dea1124c09c/image.png" alt=""></p>
<h3 id="anonymous">anonymous</h3>
<p>동일한 노드를 여러개 띄울 때 노드 이름이 겹치지 않도록 자동으로 할당하는 rospy option</p>
<h2 id="1n-통신">1:N 통신</h2>
<pre><code class="language-c">&lt;launch&gt;
        &lt;node pkg=&quot;msg_send&quot; type=&quot;teacher.py&quot; name=&quot;teacher1&quot;/&gt;
        &lt;node pkg=&quot;msg_send&quot; type=&quot;student.py&quot; name=&quot;student1&quot; output=&quot;screen&quot;/&gt;
        &lt;node pkg=&quot;msg_send&quot; type=&quot;student.py&quot; name=&quot;student2&quot; output=&quot;screen&quot;/&gt;
        &lt;node pkg=&quot;msg_send&quot; type=&quot;student.py&quot; name=&quot;student3&quot; output=&quot;screen&quot;/&gt;
&lt;/launch&gt;</code></pre>
<p><img src="https://velog.velcdn.com/images/wish-j/post/43d932e0-d6e1-4518-b7b8-1b66f1725d5c/image.png" alt=""></p>
<h2 id="n1-통신">N:1 통신</h2>
<pre><code class="language-c">&lt;launch&gt;
        &lt;node pkg=&quot;msg_send&quot; type=&quot;teacher.py&quot; name=&quot;teacher1&quot;/&gt;
        &lt;node pkg=&quot;msg_send&quot; type=&quot;teacher.py&quot; name=&quot;teacher2&quot;/&gt;
        &lt;node pkg=&quot;msg_send&quot; type=&quot;teacher.py&quot; name=&quot;teacher3&quot;/&gt;
        &lt;node pkg=&quot;msg_send&quot; type=&quot;student.py&quot; name=&quot;student1&quot; output=&quot;screen&quot;/&gt;
&lt;/launch&gt;</code></pre>
<p><img src="https://velog.velcdn.com/images/wish-j/post/d9376f38-1f9c-4bbc-a80f-5636e0d83ca2/image.png" alt=""></p>
<h2 id="nn-통신">N:N 통신</h2>
<pre><code class="language-c">&lt;launch&gt;
        &lt;node pkg=&quot;msg_send&quot; type=&quot;teacher.py&quot; name=&quot;teacher1&quot;/&gt;
        &lt;node pkg=&quot;msg_send&quot; type=&quot;teacher.py&quot; name=&quot;teacher2&quot;/&gt;
        &lt;node pkg=&quot;msg_send&quot; type=&quot;teacher.py&quot; name=&quot;teacher3&quot;/&gt;
        &lt;node pkg=&quot;msg_send&quot; type=&quot;student.py&quot; name=&quot;student1&quot; output=&quot;screen&quot;/&gt;
                &lt;node pkg=&quot;msg_send&quot; type=&quot;student.py&quot; name=&quot;student2&quot; output=&quot;screen&quot;/&gt;
        &lt;node pkg=&quot;msg_send&quot; type=&quot;student.py&quot; name=&quot;student3&quot; output=&quot;screen&quot;/&gt;
&lt;/launch&gt;</code></pre>
<p><img src="https://velog.velcdn.com/images/wish-j/post/e6a9137d-d632-4362-8cad-ac8414ff2571/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[ ROS basic]]></title>
            <link>https://velog.io/@wish-j/ROS-basic</link>
            <guid>https://velog.io/@wish-j/ROS-basic</guid>
            <pubDate>Mon, 01 May 2023 12:29:44 GMT</pubDate>
            <description><![CDATA[<h1 id="ros-핵심-기능">ROS 핵심 기능</h1>
<ul>
<li>노드간 통신을 기반으로 전체 시스템을 구동시킴</li>
</ul>
<p><img src="https://velog.velcdn.com/images/wish-j/post/d4ead475-c5f2-4042-8fdb-0799e11cfc34/image.png" alt=""></p>
<h3 id="하드웨어-제조사하-제공하는-ros-노드들">하드웨어 제조사하 제공하는 ROS 노드들</h3>
<p><img src="https://velog.velcdn.com/images/wish-j/post/319d44f7-07cc-4590-9d19-37088c57cd55/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/wish-j/post/71e5f5fb-f024-43d4-9400-17480b0b44d4/image.png" alt=""></p>
<h1 id="ros-통신">ROS 통신</h1>
<ol>
<li>토픽 방식 통신<ol>
<li>일방적이고 지속적인 메세지 전송</li>
<li>발행자-구독자 구조</li>
<li>일대 다수, 다대 다수 통신도 가능</li>
</ol>
</li>
<li>서버 방식 통신<ol>
<li>요청시, 요청한 데이터 전송</li>
<li>서버-클라이언트 구조</li>
<li>양방향 통신, 일회성 통신</li>
</ol>
</li>
</ol>
<h1 id="ros-배포판">ROS 배포판</h1>
<p>LTS: long trem support </p>
<p>→ 안정화된 버전에 대하여 지속적으로 서포트함을 의미함 </p>
<p>Ubuntu LTS</p>
<ul>
<li>18.04 LTS (codename: bionic)</li>
<li>20.04 LTS (codename: Focal)</li>
<li>22.04 LTS (codename: jammy)</li>
</ul>
<p>ROS1 LTS</p>
<ul>
<li>kinetic (with ubuntu 18.04)</li>
<li>melodic (with ubuntu 18.04)</li>
<li>notic (with ubuntu 20.04)</li>
</ul>
<p>ROS2 LTS</p>
<ul>
<li>humble (with ubuntu 22.04)</li>
</ul>
<p>*ROS 버전별 지원하는 패키지가 달라짐에 유의</p>
<p><a href="https://ubuntu.com/blog/ros-foxy-ros-melodic-eol">https://ubuntu.com/blog/ros-foxy-ros-melodic-eol</a></p>
<p><img src="https://velog.velcdn.com/images/wish-j/post/70ebeef2-1d84-407c-89c8-3367c9e98846/image.png" alt=""></p>
<p>우분투 버전에 따른 ROS 버전. ubuntu 20.04를 사용하므로 notic을 설치함.</p>
<h1 id="ros-기본-용어">ROS 기본 용어</h1>
<ul>
<li>마스터<ul>
<li>노드간 통신을 총괄 관리</li>
<li>ROS Core라 불림</li>
</ul>
</li>
<li>노드<ul>
<li>토픽을 주고받는 통신 주체</li>
<li>실행가능한 최소단위의 프로세스</li>
<li>하드웨어 장치에 하나씩 또는 소프트웨어 모듈에 하나씩</li>
</ul>
</li>
<li>토픽<ul>
<li>주고받는 메세지</li>
<li>예: 센서데이터, 카메라 이미지, 명령</li>
</ul>
</li>
<li>발행자 노드<ul>
<li>토픽(Topic)을 만들어 보내는 노드</li>
<li>예: 정보수집센서, 카메라</li>
</ul>
</li>
<li>구독자 노드<ul>
<li>토픽(Topic)을 받는 노드</li>
<li>예: 모터제어기, 정보수집 SW모듈</li>
</ul>
</li>
<li>패키지<ul>
<li>하나 이상의 노드와 노트 실행을 위한 정보등을 묶어놓은 것</li>
<li>노드, 라이브러리, 데이터, 실행파일(configration) 등을 포함</li>
</ul>
</li>
</ul>
<h1 id="ros-기본-명령어">ROS 기본 명령어</h1>
<p><img src="https://velog.velcdn.com/images/wish-j/post/0ab3273e-e8d6-4098-9d55-c665708c0fd2/image.png" alt=""></p>
<h1 id="ros-주요-명령어">ROS 주요 명령어</h1>
<p><img src="https://velog.velcdn.com/images/wish-j/post/af3007fd-f9c7-4c9a-8702-3453a60f979e/image.png" alt=""></p>
<h1 id="ros에서-제공하는-쓸만한-도구">ROS에서 제공하는 쓸만한 도구</h1>
<p><img src="https://velog.velcdn.com/images/wish-j/post/810126c8-762a-40ae-8569-9a736068e403/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/wish-j/post/f615c569-db5e-4ffd-997f-29a404fb1678/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Command Line - UNIX file mode]]></title>
            <link>https://velog.io/@wish-j/Command-Line-UNIX-file-mode</link>
            <guid>https://velog.io/@wish-j/Command-Line-UNIX-file-mode</guid>
            <pubDate>Mon, 01 May 2023 07:07:00 GMT</pubDate>
            <description><![CDATA[<h1 id="unix-file-mode">UNIX file mode</h1>
<h3 id="file-mode-bit">file mode bit</h3>
<p>UNIX의 “파일 권한”을 나타내는 3+9bit 체계 (화면에는 9칸만 표시됨)</p>
<p>3+9bit</p>
<ul>
<li>3bit : SetUID, SetGID, Sticky bit를 의미 ( 보안과 관련이 깊은 허가 권한)</li>
<li>9bit : owner, group, others 접근 권한</li>
</ul>
<p>표기 방법</p>
<ul>
<li>Symbolic mode : “rwx” sybol로 표기하는 방식</li>
<li>Octal mode : bit를 8진수 법으로 표기하는 방식 (대부분의 실무에서 사용됨)</li>
</ul>
<h3 id="octal-mode">Octal mode</h3>
<p>UNIX file mode의 8진수 표기법 (==2진수 표기 = 8진수 표기)</p>
<ul>
<li>r : readable (==2^2 = 4)</li>
<li>w : writable (==2^1 = 2)</li>
<li>x : executable (==2^0 = 1)</li>
</ul>
<p>예시</p>
<ul>
<li>rwx/rwx/rwx = owner/group/others 접근 권한 의미</li>
<li>rwx/r-x/—- = owner(rwx)/group(r-x)/others(—-)</li>
<li>(= 4+2+1 / 4+1 / 0) = 750</li>
</ul>
<p>기본값</p>
<p>파일 및 폴더 생성 시 기본 값으로 umask값을 뺀 나머지가 된다.</p>
<ul>
<li>umask = 002</li>
<li>파일 기본 값 : 666 - 002 = 644</li>
<li>폴더 기본 값 : 777 - 002 = 775</li>
</ul>
<h3 id="file-mode-권한">file mode 권한</h3>
<p>폴더</p>
<ul>
<li>r: 폴더를 읽는 기능 → 권한 없을 시 ls로 확인 안됨</li>
<li>w: 폴더내 파일 리스트를 쓰는 기능</li>
<li>x: 폴더 내 파일 리스트에 연결된 파일에 엑세스 하는 기능 → 권한 없을 시 cat으로 file 접근 안됨</li>
</ul>
<h3 id="chmod">chmod</h3>
<p>chmod : change mode</p>
<ul>
<li>ex: chmod 640 myfile</li>
<li>ex: chmod +x myfile</li>
</ul>
<h3 id="chown-chgrp">chown, chgrp</h3>
<p>chown : change owner</p>
<p>chgrp : change group</p>
<ul>
<li>root 유저만 가능한 명령어</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Commend Line - Process]]></title>
            <link>https://velog.io/@wish-j/Commend-Line-Process</link>
            <guid>https://velog.io/@wish-j/Commend-Line-Process</guid>
            <pubDate>Mon, 01 May 2023 06:55:37 GMT</pubDate>
            <description><![CDATA[<h1 id="process">Process</h1>
<h3 id="ps">ps</h3>
<p>ps [option]: process status</p>
<ul>
<li>현재 세션의 프로세스들을 보여줌</li>
<li>PID : process ID</li>
<li>TTY : terminal ID</li>
<li>TIME : <strong>cpu 점유(누적 사용) time (현실 시간은 ETIME)</strong></li>
<li>CMD : process 실행 명령어 (첫번째 인수, argv[0])</li>
</ul>
<p>option</p>
<ul>
<li>-e : select all process</li>
<li>-a : 특정 조건 제외하여 보여줌 = 세션 리더격만 확인하는 코드 (향후 다룸)</li>
<li>-f : full-format</li>
<li>-l : long-format (시스템 관리용)</li>
<li>-el: all, long</li>
<li>-ef: all, full</li>
<li>-ej: all, jobs</li>
<li>-eo: ?</li>
<li>axf: “-” 기호 없음, BSD style (UNIX 표준화 후 여러 종류의 옵션을 지원하기 시작함)</li>
</ul>
<p>full-format</p>
<ul>
<li>UIP : user ID, 프로세스의 소유권자</li>
<li>PPID : parent PID (프로세스 생성 시 부모-자식과 같은 계층 프로세스가 만들어짐)</li>
<li>C : CPU 사용량</li>
<li>STIME : 프로세스를 시작한 realtime 시간 (시:분)</li>
</ul>
<p>long-format ?</p>
<ul>
<li>F: 프로세스 플래그</li>
<li>S: 상태 코드 (S: sleep, R: )</li>
<li>PRI : 실시간 우선순위</li>
<li>NI : 나이스 우선순위</li>
<li>SZ : 메모리 크기</li>
</ul>
<p>grep</p>
<ul>
<li>ps [option] | grep [commend]</li>
<li>commend 명령을 실행한 프로세스만 표시</li>
</ul>
<h1 id="process-control">Process Control</h1>
<h3 id="kill">kill</h3>
<ul>
<li>프로세스를 죽이는 명령어? No!</li>
<li>UNIX의 kill은 이름을 잘못 지은 케이스다</li>
<li>시그널을 전송하는 기능</li>
</ul>
<p>option</p>
<ul>
<li>-l : 사용 가능한 시그널 리스트 확인 기능</li>
</ul>
<p>signal</p>
<ul>
<li><strong>SIGHUP</strong> : [-HUP] signal hagn up → 끊다, 연결이 끊어졌을 때 보내짐</li>
<li><strong>SIGINT</strong> : [-INT] signal interrupt → <CTRL-C> 키보드 입력시 발생</li>
<li>SIGQUIT : [-QUIT] signal quit → &lt;CTRL-&gt; 시스템이 이상할 때 종료하고 덤프로 확인(?)</li>
<li><strong>SIGTERM</strong> : [-TERM, 15]죽어달라고 요청하는 신호</li>
<li>SIGKILL : [default] signal kill → 죽어달라고 프로세스에 요청하는 대신 프로세스를 강제로 죽임. SIGTERM에 응답이 없을 시 최후의 수단으로 사용</li>
<li>SIGSEGV : [-SEGV] signal segment violation → 허용되지 않은 방법으로 메모리 침범 시도시 발생하는 시그널. 세그폴트</li>
<li><strong>SIGTSTP</strong> :  [-TSTP] signal Temporary Stop <CTRL-Z> 잠시 정지</li>
</ul>
<h2 id="job-control">job control</h2>
<h3 id="controlling-terminal">controlling terminal</h3>
<p>사용자의 제어(키보드 입력)를 받는 터미널 장치</p>
<ul>
<li>CUI (console user interface)에서 멀티 테스킹을 위한 제어 방법</li>
<li>제어 터미널을 소유한 프로세스 (=fore-ground process) 는 키보드 입력을 가진다.</li>
<li>하나의 세션에서는 하나의 제어 터미널을 가질 수 있다.</li>
</ul>
<p>규격</p>
<p>→ ps 명령어 출력의 TTY 필드에 표기</p>
<ul>
<li><p>pts/# : UNIX98 Pseudo terminal system (가상 터미널)</p>
</li>
<li><p>tty# : console terminal (진짜 사용자 입력을 받는 콘솔 터미널 &lt;CTRL-ALT-F#&gt; 로 전환 : tty3, tty2…)</p>
</li>
<li><p>? : 제어 터미널을 가지지 않는 경우</p>
</li>
<li><p>참고: 규격의 발전</p>
<ul>
<li>1998 SUSv2 (표준)</li>
<li>1995 SUSv1</li>
<li>1988 SVR4 (현대 UNIX의 모태)</li>
</ul>
</li>
</ul>
<h3 id="foreback-ground-process">fore/back-ground process</h3>
<ul>
<li>fore-ground process<ul>
<li>현재 session에서 제어 터미널(controlling terminal)을 가진 프로세스</li>
</ul>
</li>
<li>back-ground process<ul>
<li>현재 session에서 제어 터미널(controlling terminal)을 잃어버린 프로세스</li>
</ul>
</li>
<li>CTRL-Z 시 변화<ul>
<li>SIGTSTP 시그널을 fore-ground 프로세스에 전달</li>
<li>작동 : 잠시 정지 시킴 = back-ground에 Stopped 상태로 전환됨</li>
</ul>
</li>
</ul>
<h3 id="session-">session ?</h3>
<p>멀티 유저 시스템에서 통신 객체 (seat or remote)를 구별하기 위함</p>
<ul>
<li>제어 터미널을 가질수도 안가질 수도 있다</li>
<li>시스템 접근 시 터미널에서 작업할 때 작업 공간을 만든 것 자체 = 세션을 받았다</li>
<li>SID (session ID) == PID (process ID) 인 process = Session Leader<ul>
<li>Process Grop Leader를 겸한다</li>
<li>Session Leader로 부터 파생된 자식 프로세스는 모두 같은 세션을 가진다.</li>
<li>이는 접속(세션 생성) 후 해당 프로세스가 어디서 유래했는지 추적인 가능하기 때문에 중요한 의미를 가짐</li>
</ul>
</li>
</ul>
<h3 id="prosess-group">prosess group</h3>
<p>세션이 만들어진 후 내린 명령으로 실행된 프로세스들의 계층</p>
<p>음수 번호로 적힌 프로세스 아이디 = 프로세스 그룹 아이디</p>
<h2 id="commands">commands</h2>
<h3 id="jobs-fg--bg--command">jobs, fg %#, bg %#, command &amp;</h3>
<p>jabs : stoped, back-ground process의 리스트 출력</p>
<p>fg %#: jobs의 작업 번호 입력 → 지정한 process를 fore-ground로 전환, 실행</p>
<p>bg %#:  jobs의 작업 번호 입력 → 정지된 process를 back-ground에서 실행</p>
<p>command &amp;: back-ground에서 running 상태로 실행</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Commend Line - Archive, Compress]]></title>
            <link>https://velog.io/@wish-j/Commend-Line-Archive-Compress</link>
            <guid>https://velog.io/@wish-j/Commend-Line-Archive-Compress</guid>
            <pubDate>Mon, 01 May 2023 06:54:06 GMT</pubDate>
            <description><![CDATA[<h1 id="archive-compress">Archive, Compress</h1>
<ul>
<li>아카이브 유틸 : tar (tape archive), cpio<ul>
<li>단순히 테이프에 보관하는 목적</li>
<li>BSD와 SysV에 의해 명령어가 두개로 분리됨</li>
</ul>
</li>
<li>압축 유틸 : gzip, bzip2, xz, zstd, lz4<ul>
<li>압축, 압축해제 명령어</li>
<li>압축률 : xz &gt; bzip2, <strong>zstd</strong> &gt; gzip &gt; lz4 순</li>
</ul>
</li>
</ul>
<h3 id="tar">tar</h3>
<p>tar [ctxv] [f archive-file] files…</p>
<ul>
<li><p>c : (create)</p>
</li>
<li><p>t : (test)</p>
</li>
<li><p>x : (extract)</p>
</li>
<li><p>v : (verbose) 상세한 정보 출력 → 실무에서는 쓰지 않는다!</p>
</li>
<li><p>f archive-file : 입출력할 아카이브 파일명 (리디렉션 대신 사용)</p>
</li>
<li><p>—exclude file : 특정 file을 제외</p>
</li>
</ul>
<h3 id="compress">compress</h3>
<ul>
<li>xz : 확장자 xz<ul>
<li>텍스트 압축에 압도적으로 강하나, 느리다 (소스코드 압축)</li>
</ul>
</li>
<li>zstd : 확장자 zst<ul>
<li>속도가 많이 빠르다. 주로 사용 명령어</li>
</ul>
</li>
<li>gzip [-cdflrv] &lt;file …&gt;<ul>
<li>-d : (decompress) 압축해제</li>
<li>-c : (stdout) 표준 출력(stdout)으로 결과물을 보냄</li>
<li>-1, -9 (fast, better) 압축 레벨 지정</li>
</ul>
</li>
<li>tar와 gzip을 함께 사용하는 방법<ul>
<li>압축: tar c ./data ./exp | gzip -c &gt; bak_data.tar.gz</li>
<li>해제: gzip -dc c bak_data.tar.gz | tar x</li>
</ul>
</li>
</ul>
<h3 id="practice--tar-compression">Practice : tar, compression</h3>
<h3 id="tar-1">tar</h3>
<p><strong>고전 명령어</strong> (multi 쓰레드 사용 가능)</p>
<p>tar c ./data ./exp | gzip -c &gt; bak_data.tar.gz</p>
<p><strong>르네상스 명령어</strong></p>
<p>tar cfz bak_data.tar.gz  ./data ./exp</p>
<p>tar cfj bak_data.tar.bz2  ./data ./exp</p>
<p>tar cfJ bak_data.tar.xz ./data ./exp</p>
<p><strong>모던 명령어</strong> (tar zstd 1.31부터 지원, 멀티 스레드 안됨)</p>
<p>tar cfa bak_data.tar.xz  ./data ./exp</p>
<p>tar cfa bak_data.tar.zst  ./data ./exp</p>
<p><strong>모던 멀티 스레드 명령어</strong></p>
<p>tar c ./data ./exp | xz -c -T0 &gt; bak_data.tar.xz</p>
<p>tar c ./data ./exp | zsted -c -T0 &gt; bak_data.tar.zst</p>
<h3 id="compression">compression</h3>
<p><strong>고전 명령어</strong> (multi 쓰레드 사용 가능)</p>
<p>gzip -dc c bak_data.tar.gz | tar x</p>
<p><strong>르네상스 명령어</strong></p>
<p>tar xfz bak_data.tar.gz  </p>
<p>tar xfj bak_data.tar.bz2 </p>
<p>tar xfJ bak_data.tar.xz </p>
<p><strong>모던 명령어</strong> (tar zstd 1.31부터 지원, 멀티 스레드 안됨)</p>
<p>tar xfa bak_data.tar.xz </p>
<p>tar xfa bak_data.tar.zst </p>
<p><strong>모던 멀티 스레드 명령어</strong></p>
<p>xz -dcT0 bak_data.tar.xz | tar x</p>
<p>zstd -dcT0 bak_data.tar.zst | tar x</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Commend Line - Stdio]]></title>
            <link>https://velog.io/@wish-j/Commend-Line-Stdio</link>
            <guid>https://velog.io/@wish-j/Commend-Line-Stdio</guid>
            <pubDate>Mon, 01 May 2023 06:53:14 GMT</pubDate>
            <description><![CDATA[<h1 id="stdio">Stdio</h1>
<h3 id="stdio-1">stdio</h3>
<p>stdio: standard Input/Output (표준입출력)</p>
<h3 id="file-channel">file channel</h3>
<ul>
<li>하드웨어 내 file에 입출력 하기 위한 통로</li>
<li>입출력 하기 위한 메타 정보를 가지는 객체, 프로세스 스코프에서 유효함, 프로세스 종료 시 휘발됨</li>
</ul>
<h3 id="file-descripter">file descripter</h3>
<p>fd, 파일 서술자</p>
<ul>
<li>파일 채널들에게 붙여지는 숫자 형태의 식별자</li>
<li>0번 부터 시작</li>
</ul>
<p>예약된 파일 서술자</p>
<ul>
<li>0: stdin (standard input, 표준입력)</li>
<li>1: stdout (standard output, 표준출력)</li>
<li>2: stderr (standard input, 표준에러)</li>
</ul>
<h2 id="pipe">PIPE</h2>
<p>프로세스 사이에 통신하기 위해 사용됨</p>
<p>IPC(Inter-Process Communication)의 일종</p>
<p>Shell에서도 많이 사용하는 기능</p>
<p>pipe의 종류 2가지</p>
<ul>
<li>anonymous pipe (temporary)</li>
<li>named pip (persistency)</li>
</ul>
<h3 id="anonymous-pipe">anonymous pipe</h3>
<p><strong>임시로 생성</strong>되었다가 소멸되는 파이프 (nameless pipe, unamed pipe)</p>
<ul>
<li><p>프로세스들의 <strong>직렬 연결</strong>하는 기능</p>
</li>
<li><p>셸 명령행에서 <strong>Vertical bar (|)로 사용</strong></p>
<ul>
<li>A | B | C</li>
</ul>
</li>
<li><p>셸의 stdio에서 주로 배우는 개념</p>
</li>
<li><p>일반적으로 ‘파이프’라고 부르면 익명 파이프임</p>
</li>
<li><p>사용 예</p>
<p>  $ find ~ | wc -l  (홈 디렉토리의 파일 개수를 새는 명령어)</p>
<p>  $ find ~ &gt; tmp.txt; wc -l &lt; tmp.txt; rm tmp.txt (같은 작업이 파이프를 사용하지 않으면 길어짐)</p>
<p>  process1: find 명령의 출력 (stdout, 1)</p>
<p>  process2: wc 명령의 입력 (stdin, 0)</p>
<p>  프로세스의 입출력 채널이 서로 연결됨</p>
</li>
</ul>
<h3 id="named-pipe">named pipe</h3>
<p>명명된 파이프 (FIFO Pipe)</p>
<ul>
<li>FIFO 규칙으로 작동함</li>
<li>file 처럼 구성됨 = path, filename이 존재</li>
<li>따라서 path를 가지는 것을 곧 명명되었다고 표현함</li>
<li>mkfifo 명령 (or POSIX C API)를 사용하여 생성</li>
</ul>
<h3 id="redirection">Redirection</h3>
<p>채널의 방향을 다른곳으로 지정 (방향재지정)</p>
<ul>
<li><p>A &gt; B : A의 stdout을 파일 B로 연결</p>
</li>
<li><p>A &lt; B : B stdout을 파일 A로 연결</p>
</li>
<li><p>A &gt;&gt; B : append mode로 기존 데이터를 지우지 않고 추가됨</p>
</li>
<li><p>사용 예</p>
<p>  sort &lt; names.txt</p>
<p>  ls &gt; filelist1.txt ( &gt; = 1&gt;)</p>
<p>  strace ls 2&gt; strace.txt (stderror, 2 (error 출력)을 txt에 저장)</p>
</li>
</ul>
<h3 id="cat">Cat</h3>
<p>stdout과 파일을 자유롭게 연결해주는 기본 필터</p>
<ul>
<li>용도 - 파일의 내용을 stdout으로 출력</li>
<li>용도 -  stdin의 입력을 redirection해서 파일로 출력하는 용도</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Commend Line - link]]></title>
            <link>https://velog.io/@wish-j/Commend-Line-link</link>
            <guid>https://velog.io/@wish-j/Commend-Line-link</guid>
            <pubDate>Mon, 01 May 2023 06:52:22 GMT</pubDate>
            <description><![CDATA[<h1 id="file---link">File - link</h1>
<h3 id="in">In</h3>
<p>make links</p>
<ul>
<li>하드 링크 (hard link)</li>
<li>심볼릭 링크 (symbolic link, symlink, -s)</li>
</ul>
<p>용도</p>
<ul>
<li>library 버전 관리</li>
<li>build 시 정적 빌드시 용량을 많이 차지함. 대신 동적 빌드 o</li>
</ul>
<h3 id="개념---파일-저장-i-node와-link">개념 - 파일 저장 (i-node와 link)</h3>
<p>file은 파일 경로와 데이터로 구성되어 있다. </p>
<p>file의 데이터에 접근할 때, </p>
<p>i-node를 통해서 하드웨어에 저장된 실제 데이터를 접근한다.</p>
<p>파일 경로로 부터 i-node를 연결하는 기능이 필요하고 이를 hardlink라 한다.</p>
<p>따라서 File을 복제 하였을 때, </p>
<p>데이터가 복사되어 새로운 하드웨어 메모리를 차지하는 것이 아니라,</p>
<p>같은 i-node를 가리키는 hardlink가 추가로 생성되어 추가 메모리를 소요하지 않는다.</p>
<p>symlink는 완전히 다른 파일로, 단지 특정 <strong>파일의 경로</strong>를 가리키는 기능을 한다. (윈도우의 파일 및 폴더 바로가기 생성)</p>
<h3 id="i-node-i-num">i-node (i-num)</h3>
<p>파일의 <strong>메타 정보</strong>를 가지고 관리하는 객체</p>
<ul>
<li>시간 관련 정보, 사이즈, 소유권, 권한 … 등</li>
<li>파일은 고유의 i-node를 1개 가지고 있다.</li>
<li>i-node는 disk partition(volume) 내에서만 유효한 식별자다.</li>
<li>다른 disk에서 i-node는 의미 없는 번호</li>
</ul>
<h3 id="hard-link">hard link</h3>
<ul>
<li>ln [original file] [hardlink file]</li>
<li>same i-node를 가리키므로 동일(실체 파일과 하드링크파일이)ㅇ션파티티에내서에만   능가</li>
<li>regular file(일반 파일, 데이터 실체를 가진 파일)에만 생성이 가능함.</li>
<li><strong>unregular file</strong> (directory, device file) 등은 생성이 불가능함</li>
</ul>
<h3 id="symbolic-link-symlink">symbolic link (symlink)</h3>
<ul>
<li>ln -s [original file] [symlink file]</li>
<li>ln -sr hello.txt ../symhello.txt</li>
<li>기능: 위치(path)만 가리키므로 다른 파티션, 모든 종류의 file에 생성</li>
<li>권한: 777, 의미는 없다</li>
<li>bronken error방지<ul>
<li>symlink 생성시 [original file]의 경로를 입력한 그대로 연결하기 때문에, symlink 폴더 위치로 이동해서 symlink 폴더 위치를 기준으로 [original file] 경로를 지정해주어야 한다.</li>
</ul>
</li>
</ul>
<h3 id="readlink">readlink</h3>
<p>readlink [-fe] <symlink></p>
<p>symlink의 canonical path 식별</p>
<ul>
<li>symlink → symlink → … → symlink → hardlink<ul>
<li>readlink -f <symlink> : 마지막 링크를 제외하고</li>
<li>readlink -e <symlink> : 전체 링크</li>
</ul>
</li>
</ul>
<h3 id="개념---canonical-blah">개념 - canonical <blah></h3>
<p>canonical : 실체화, 실체를 가지는 standard, official의 의미를 가짐</p>
<p>../../와 같은 상대 주소는 cwd에 따라 가르키는 위치가 달라짐</p>
<p>. (현재 디렉토리, cwd)가 정의되면 cwd를 기준으로 ../../를 official한 값으로 해석할 수 있다. </p>
<p>(A의) 옆집과 같이 A나 B가 정해져야만 official한 의미가 되는 경우, 상대적인 의미를 해석한 뒤 standard, official의 대상을 한정하는 행위를 canonicalization이라고 표현한다.</p>
<p>symlink는 실체를 가리키는게 아니기 때문에 따라가기 전에는 대상을 한정할 수 없다. 그러므로 순차적으로 따라가야 canonical path를 알 수 있게 된다.</p>
<h3 id="which">which</h3>
<p>which [commend]</p>
<ul>
<li>PATH에 존재하는 파일을 검색</li>
<li>명령어가 어디있는지 알야 할 때 사용</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Motion Planning & Control Overview]]></title>
            <link>https://velog.io/@wish-j/Motion-Planning-Control-Overview</link>
            <guid>https://velog.io/@wish-j/Motion-Planning-Control-Overview</guid>
            <pubDate>Mon, 01 May 2023 06:41:01 GMT</pubDate>
            <description><![CDATA[<h1 id="mission">Mission</h1>
<p><strong>차로 변경 안전성 향상을 위한 Responsibility-Sensitive Safety(RSS) 기반 확률론적 충돌 위험도 추정</strong></p>
<p><a href="https://www.dbpia.co.kr/journal/articleDetail?nodeId=NODE11220037">https://www.dbpia.co.kr/journal/articleDetail?nodeId=NODE11220037</a></p>
<h2 id="scenario-1-전측방-차량-사이로-차선-변경">Scenario 1: 전측방 차량 사이로 차선 변경</h2>
<p>전략</p>
<ul>
<li>Target1의 <strong>양보 의도 판단</strong> 후 위험도 감소</li>
<li>Target2의 위험도를 줄이기 위해 자차 감속 후 차선변경 시도</li>
</ul>
<p>관측</p>
<table>
<thead>
<tr>
<th></th>
<th>Ego</th>
<th>Target1</th>
<th>Target2</th>
</tr>
</thead>
<tbody><tr>
<td>Velocity</td>
<td>O</td>
<td>O</td>
<td>O</td>
</tr>
<tr>
<td>LC Risk</td>
<td>O</td>
<td>O</td>
<td>O</td>
</tr>
<tr>
<td>Intention</td>
<td></td>
<td>O</td>
<td></td>
</tr>
<tr>
<td>Maneuver</td>
<td>O</td>
<td></td>
<td></td>
</tr>
</tbody></table>
<h2 id="scenario-2-차선-변경-중-후측방-차량의-가속으로-차선변경-취소">Scenario 2: 차선 변경 중 후측방 차량의 가속으로 차선변경 취소</h2>
<p>전략</p>
<ul>
<li>추월하는 Target1이 지나간 이후 차선 변경 시도 (위험도 0.2)</li>
<li>차선변경 중 Target2 감지하여 차선 변경 취소 동작 작동 (위험도 0.6)</li>
</ul>
<table>
<thead>
<tr>
<th></th>
<th>Ego</th>
<th>Target1</th>
<th>Target2</th>
</tr>
</thead>
<tbody><tr>
<td>Velocity</td>
<td>O</td>
<td>O</td>
<td>O</td>
</tr>
<tr>
<td>LC Risk</td>
<td>O</td>
<td>O</td>
<td>O</td>
</tr>
<tr>
<td>Maneuver</td>
<td>O</td>
<td></td>
<td></td>
</tr>
</tbody></table>
<h2 id="scenario-3-차선-종류에-따른-차선-변경-차이">Scenario 3: 차선 종류에 따른 차선 변경 차이</h2>
<p>전략</p>
<ul>
<li>타겟의 종류를 인지하여 종류에 따른 RSS parameter를 업데이트<ul>
<li>대형차 인식 시 RSS parameter의 반응시간 증가, 제동력 감소로 충돌 안전거리 증가</li>
<li>대형차 인식 충돌 위험도 증가로 중형차 보다 안전한 차선 변경 시도</li>
</ul>
</li>
</ul>
<h1 id="motion-planning-and-control">Motion Planning and Control</h1>
<p><img src="https://velog.velcdn.com/images/wish-j/post/c02016d5-2da7-4b86-ac30-e7955c16dc10/image.png" alt="우버에서 제안한 Autonomous Driving Process"></p>
<p>우버에서 제안한 Autonomous Vehicle diagram Process</p>
<h3 id="perception">Perception</h3>
<ol>
<li>Sensors<ul>
<li>LiDAR</li>
<li>Radar</li>
<li>Cameras</li>
<li>GPS</li>
<li>IMU</li>
<li>Encoders</li>
</ul>
</li>
<li>Maps &amp; Localization : 위치 추정</li>
<li>Perception : 센서를 통해 감지된 사물을 분류하고 인지하는 것<ol>
<li>Line Detection</li>
<li>Traffic Light</li>
<li>Trafftic Sign</li>
<li>Object Detection</li>
<li>Free Space Detection</li>
</ol>
</li>
<li>Prediction : 인식된 물체의 의도를 파악하고 주행 경로를 예측하는 것</li>
</ol>
<h3 id="control">Control</h3>
<ol>
<li>Input Destination : 목적지를 입력</li>
<li>Routing : 목적지까지 가는 길 (Global Planning)</li>
<li>Motion Planning : 인지 정보를 활용하여 안전하고 편안한 경로를 계획하는 것<ol>
<li>인지 정보: 교차로, 우회전 상황, 보행자가 횡단번호를 지나가지 않는 상황</li>
<li>움직임 계획: 정지선 앞에서 일시정지, 사람이 없으면 천천히 지나가!</li>
</ol>
</li>
<li>Vehicle Control<ol>
<li>수많은 외란을 핸들하는 제어기 설계 필요</li>
</ol>
</li>
<li>Actuators<ol>
<li>Accelerator</li>
<li>Brakes</li>
<li>Steering</li>
<li>Signals</li>
</ol>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[OpenCV noise]]></title>
            <link>https://velog.io/@wish-j/OpenCV-noise</link>
            <guid>https://velog.io/@wish-j/OpenCV-noise</guid>
            <pubDate>Mon, 01 May 2023 03:41:17 GMT</pubDate>
            <description><![CDATA[<h2 id="image-filtering">Image Filtering</h2>
<p>Nosize 제거 기법 (Smoothing)</p>
<ul>
<li>Neighborhood of a pixel</li>
<li>Image Averaging</li>
<li>Convolution</li>
<li>Gaussian Blur</li>
<li>medianBlur (for Salt&amp;pepper noise)</li>
<li>bilaterFilter (경계선을 제외하고 블러링)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[OpenCV edge detection]]></title>
            <link>https://velog.io/@wish-j/OpenCV-edge-detection</link>
            <guid>https://velog.io/@wish-j/OpenCV-edge-detection</guid>
            <pubDate>Mon, 01 May 2023 03:40:15 GMT</pubDate>
            <description><![CDATA[<h2 id="edge-detection">edge detection</h2>
<p>edge는 물체의 경계인 경우가 많으므로 edge 추출 → 물체 추출을 수행할 수 있음</p>
<p>정의</p>
<ul>
<li>에지 화소: 영상 함수의 밝기가 급격하게 변하는 화소</li>
<li>에지 : 연결된 에지 화소의 집합</li>
</ul>
<p>타입</p>
<ul>
<li>계단 에지 : 이상적인 에지</li>
<li>비탈 에지 : 일반적인 디지털 영상의 경계에서 나타나는 노이즈 현상</li>
<li>지붕 에지 : 영역을 지나는 선</li>
</ul>
<h3 id="finding-edges">Finding Edges</h3>
<ul>
<li>Dirivatives in Continuous Domain<ul>
<li>이론 정리 필요</li>
</ul>
</li>
</ul>
<h3 id="sobel-filter">Sobel Filter</h3>
<p>→ 멀리 있는 픽셀 값보다 가까이 있는 픽셀 값이 더 중요하다는 논리</p>
<table>
<thead>
<tr>
<th>명령어</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>Sobel</td>
<td>kernel, scale, delta을 지정하여 이미지의 엣지 검출을 수행</td>
</tr>
</tbody></table>
<h3 id="canny-edge-detector">Canny Edge Detector</h3>
<p>→ sobel filter의 단점 (굵기 변화, 노이즈)를 개선하는 방법</p>
<p><strong>key idea</strong></p>
<ol>
<li>Non-Maximum Suppression: thining the edges</li>
</ol>
<p>→ blur한 영역의 에지들을 제거</p>
<ul>
<li>수평, 수직 미분값의 벡터합으로 gradient 계산 → 같은 방향(기울기)(=같은 gradient) 값을 가진 인접 픽셀들의 크기를 비교하여 가장 큰 픽셀만 에지로 남김</li>
</ul>
<ol>
<li>Double Threshold</li>
</ol>
<p>→ 노이즈로 인한 false positive 제거</p>
<table>
<thead>
<tr>
<th>구분</th>
<th>기준</th>
</tr>
</thead>
<tbody><tr>
<td>strong edge</td>
<td>high threshold 이상 엣지</td>
</tr>
<tr>
<td>week edge</td>
<td>high threshold 이하 low threshold 이상 엣지 <br> → 인접한 8개의 pixel이 strong edge일 때 strong edge로 분류됨</td>
</tr>
<tr>
<td>nagative</td>
<td>low threshold 이하 엣지, 제거됨</td>
</tr>
</tbody></table>
<p><strong>commend</strong></p>
<table>
<thead>
<tr>
<th>명령어</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>Canny</td>
<td>threshold1, threshold2, ksize을 지정하여 이미지의 엣지 검출을 수행</td>
</tr>
</tbody></table>
]]></description>
        </item>
        <item>
            <title><![CDATA[OpenCV binarization]]></title>
            <link>https://velog.io/@wish-j/OpenCV-binarization</link>
            <guid>https://velog.io/@wish-j/OpenCV-binarization</guid>
            <pubDate>Mon, 01 May 2023 03:38:26 GMT</pubDate>
            <description><![CDATA[<h1 id="binarization"><strong>binarization</strong></h1>
<p>이진화</p>
<p>→ 문턱값을 기준으로 픽셀을 분류한 결과에 따라 값을 재설정하는 작업</p>
<p>→ 이미지 내 관심 객체를 추출</p>
<p>단일 문턱치 처리</p>
<ul>
<li>전역적 문턱치: 단일 문턱치 사용</li>
<li>가변적 문턱치: 영상 내 각 영역에 따라 다른 문턱치 값을 적용</li>
</ul>
<h3 id="threshold-function">threshold function</h3>
<table>
<thead>
<tr>
<th>명령어</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>Threshold</td>
<td>input MAT에 문턱값을 적용하여 max_val값으로 이진화한 이미지를 output MAT에 저장</td>
</tr>
</tbody></table>
<p>flags</p>
<table>
<thead>
<tr>
<th>threshold type</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>THRESHOLD_BINARY</td>
<td>일반적인 문턱치 처리</td>
</tr>
<tr>
<td>THRESHOLD_BINARY_INV</td>
<td>THRESHOLD_BINARY의 결과를 반전시킴</td>
</tr>
<tr>
<td>THRESHOLD_TRUNC</td>
<td>문턱값 초과시 문턱값을 적용하고, 이하시 원래 값 유지 (max를 지정하는 것과 같음)</td>
</tr>
<tr>
<td>THRESHOLD_TOZERO</td>
<td>문턱값 이하시 0값을 적용하고, 초과시 원래 값 유지 (min를 지정하는 것과 같음..?)</td>
</tr>
<tr>
<td>THRESHOLD_TOZERO_INV</td>
<td>THRESHOLD_TOZERO의 결과를 반전시킴</td>
</tr>
<tr>
<td>THRESHOLD_OTSU</td>
<td>두개의 피크를 구분하는 문턱값을 찾음</td>
</tr>
</tbody></table>
<h3 id="adaptivethreshold">adaptiveThreshold</h3>
<p>→ pixel마다 적절한 thrshold를 자동으로 구함
기준: 이웃한 픽셀의 평균값에 -C 더한 값</p>
<table>
<thead>
<tr>
<th>명령어</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>adaptiveThreshold</td>
<td>input MAT에 커널사이즈, C값을 적용하여 자동으로 이진화한 이미지를 output MAT에 저장</td>
</tr>
</tbody></table>
<p>flags</p>
<table>
<thead>
<tr>
<th>threshold type</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>ADAPTIVE_THRESH_MEAN_C</td>
<td>주변 픽셀의 평균값으로 계산</td>
</tr>
<tr>
<td>ADAPTIVE_THRESH_GAUSSIAN_C</td>
<td>주변 픽셀에 가우시안 커널을 적용한 값으로 계산</td>
</tr>
</tbody></table>
<h3 id="inrange">inrange</h3>
<p>→ 2개의 문턱값 설정하여 안 범위에 든 픽셀 추출</p>
<p>→ HSV 컬러 영역에서 H값으로 이진화</p>
<table>
<thead>
<tr>
<th>명령어</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>inRange</td>
<td>hsv 이미지를 입력으로 받아 Scale로 구성된 2개의 문턱값을 설정하여 이진화</td>
</tr>
</tbody></table>
<h3 id="mopology">mopology</h3>
<p>→ 팽창, 침식의 과정을 연속으로 수행</p>
<p>노이즈 제거, 객체 추출을 위해 사용됨</p>
<table>
<thead>
<tr>
<th>명령어</th>
<th>뜻</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>dilate</td>
<td>침식 (dilation)</td>
<td>kernel, anchor, iteration을 지정하여 이미지의 침식 연산을 수행</td>
</tr>
<tr>
<td>erode</td>
<td>팽창 (erosion)</td>
<td>kernel, anchor, iteration을 지정하여 이미지의 팽창 연산을 수행</td>
</tr>
</tbody></table>
<p>flags</p>
<table>
<thead>
<tr>
<th>명령어</th>
<th>뜻</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>morphologyEx(CV_MOP_OPEN)</td>
<td>침식 (opening)</td>
<td>화이트 노이즈를 제거하기 위해 침식 → 팽창 수행</td>
</tr>
<tr>
<td>morphologyEx(CV_MOP_CLOSE)</td>
<td>팽창 (closing)</td>
<td>블랙 노이즈를 제거하기 위해 팽창 → 침식 수행</td>
</tr>
</tbody></table>
]]></description>
        </item>
        <item>
            <title><![CDATA[OpenCV Basic Commend]]></title>
            <link>https://velog.io/@wish-j/OpenCV-Basic-Commend</link>
            <guid>https://velog.io/@wish-j/OpenCV-Basic-Commend</guid>
            <pubDate>Mon, 01 May 2023 03:34:56 GMT</pubDate>
            <description><![CDATA[<h2 id="processing">Processing</h2>
<h3 id="image-video-drawing">image, video, drawing</h3>
<p>image read, write, display</p>
<table>
<thead>
<tr>
<th>명령어</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>imread</td>
<td>이미지 읽어오기</td>
</tr>
<tr>
<td>imwrite</td>
<td>이미지 저장하기</td>
</tr>
<tr>
<td>namedWindow</td>
<td>윈도우 생성</td>
</tr>
<tr>
<td>imshow</td>
<td>윈도우에 이미지 표시</td>
</tr>
<tr>
<td>waitKey</td>
<td>키보드 입력이 들어올 때까지 대기</td>
</tr>
<tr>
<td>destroyWindow</td>
<td>윈도우 제거</td>
</tr>
</tbody></table>
<p>Video display</p>
<table>
<thead>
<tr>
<th>명령어</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>VideoCapture capture</td>
<td>동영상 파일 열기</td>
</tr>
<tr>
<td>capture &gt;&gt; frame</td>
<td>동영상 파일로 부터 1 frame 이미지 읽어오기</td>
</tr>
</tbody></table>
<p>Drawing on a frame</p>
<table>
<thead>
<tr>
<th>명령어</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>line</td>
<td>두개의 점을 지정하여 선 그리기</td>
</tr>
<tr>
<td>rectangle</td>
<td>두개의 점을 지정하여 직사각형 그리기</td>
</tr>
<tr>
<td>circle</td>
<td>원점 좌표, 반지름을 지정하여 원 그리기</td>
</tr>
<tr>
<td>putText</td>
<td>시작점, 텍스트를 지정하여 글자 적기</td>
</tr>
</tbody></table>
<h3 id="color">color</h3>
<table>
<thead>
<tr>
<th>명령어</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>cvtColor</td>
<td>input MAT의 Pixel Type(flag)을 변경하여  output MAT에 저장</td>
</tr>
</tbody></table>
<p>flags</p>
<ul>
<li>COLOR_<pixeltype>2<pixeltype><ul>
<li>e.g. COLOR_BGR2RGB</li>
</ul>
</li>
</ul>
<h3 id="split">split</h3>
<table>
<thead>
<tr>
<th>명령어</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>split</td>
<td>split(Mat, vector<Mat>)</td>
</tr>
<tr>
<td>N channel img → 1 channel img * N</td>
<td></td>
</tr>
<tr>
<td>merge</td>
<td>merge(vector<Mat>, Mat)</td>
</tr>
<tr>
<td>1 channel img * N → N channel img</td>
<td></td>
</tr>
</tbody></table>
<h3 id="region-of-interest">Region of Interest</h3>
<table>
<thead>
<tr>
<th>명령어</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>Rect</td>
<td>Mat M (Mat, Rect);</td>
</tr>
<tr>
<td>변수 선언시 관심영역 지정</td>
<td></td>
</tr>
</tbody></table>
<ul>
<li>주의점 원본과 동일한 데이터를 가리키는 포인터로 기능하므로</li>
</ul>
<p>관심 영역에 대한 데이터 변경 시 원본 데이터가 변경됨</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[OpenCV Mat]]></title>
            <link>https://velog.io/@wish-j/OpenCV-Mat</link>
            <guid>https://velog.io/@wish-j/OpenCV-Mat</guid>
            <pubDate>Mon, 01 May 2023 03:34:12 GMT</pubDate>
            <description><![CDATA[<h1 id="data-structure">data structure</h1>
<h3 id="mat">Mat</h3>
<ul>
<li>Mat Object</li>
<li><strong>images</strong> in OpenCV <strong>are stored in a Mat Object</strong></li>
</ul>
<p>consists of</p>
<ul>
<li>header</li>
<li>a pointer to the matrix containing pixel values</li>
</ul>
<p>주의점</p>
<ul>
<li>mat은 body data를 가리키는 포인터로 동작함</li>
</ul>
<p>→ 복사시 동일한 body data를 가리키는 것을 원하지 않을 경우 변수명.clone() 함수를 사용</p>
<h3 id="image-types">Image Types</h3>
<p>Type of Mat object</p>
<ul>
<li>이진 데이터를 해석하는 방법을 정의함</li>
</ul>
<p>Represent</p>
<ul>
<li>CV_<DataType>C&lt;#Channel&gt;<ul>
<li>e.g. CV_8UC3: 8-bit/pixel , 3 channel</li>
</ul>
</li>
</ul>
<p>Pixel Type</p>
<ul>
<li>BGR (default)</li>
<li>GRAYSCALE</li>
<li>HSV</li>
<li>YUV</li>
<li>…</li>
</ul>
<h3 id="creating-mat">Creating Mat</h3>
<ul>
<li><p>Mat M;</p>
</li>
<li><p>Mat M (rows, colums, pixel_type);</p>
</li>
<li><p>Mat M (rows, colums, pixel_type, Scalar(initial_value));</p>
</li>
<li><p>Mat M (Size(colums, rows), pixel_type, Scalar(initial_value));</p>
</li>
<li><p>body data는 RGB가 아닌 BGR로 저장된다.</p>
</li>
</ul>
<p>→ Scalar(B value,G value,R value)</p>
<h3 id="accessing-information">Accessing Information</h3>
<p>Access to Mat Information</p>
<ul>
<li>Mat.type() - return data type</li>
<li>Mat.depth() - return number of bytes for a matrix element</li>
</ul>
<p>Access to Mat Pixels</p>
<ul>
<li>Mat.at <datatype>(row,col)[channel] : returns a pointer to the image data</li>
</ul>
<h3 id="mat-size">Mat Size</h3>
<p>Size = #colums * #rows *#channels * channel depth</p>
<ul>
<li>Mat.colums</li>
<li>Mat.rows</li>
<li>Mat.channels</li>
<li>Mat.elemSize1 - 채널당 비트수</li>
<li>Mat.elemSize - 한 픽샐당 크기(채널수 * 비트수)</li>
</ul>
<h3 id="pointer">Pointer</h3>
<ul>
<li>src(원본 데이터)와 dst(복사 데이터)의 body data 공유 (shallow copy)</li>
<li>원본 데이터를 공유하지 않고 독립적으로 할당하는 방법 필요 (deep copy)<ul>
<li>기억장소 추가 할당 + 이미지 데이터 복사</li>
<li>clone()</li>
<li>copyTo(Mat)</li>
</ul>
</li>
</ul>
]]></description>
        </item>
    </channel>
</rss>