<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Woo-Jin Han.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Mon, 08 Jan 2024 01:14:13 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>Woo-Jin Han.log</title>
            <url>https://velog.velcdn.com/images/gks970113-woo/profile/2084cae2-1cf2-4d54-9cd2-1d73de780a3b/social_profile.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. Woo-Jin Han.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/gks970113-woo" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Automotive V-Model]]></title>
            <link>https://velog.io/@gks970113-woo/Automotive-V-Model</link>
            <guid>https://velog.io/@gks970113-woo/Automotive-V-Model</guid>
            <pubDate>Mon, 08 Jan 2024 01:14:13 GMT</pubDate>
            <description><![CDATA[<h2 id="v-modelv-cycle">V-Model(V-Cycle)</h2>
<p>V-Model 혹은 V-Cycle이라고 불린다. V 모델은 소프트웨어 개발 프로세스로 폭포수 모델의 확장된 형태 중 하나이다. 말 그대로 V자 형태로 개발이 진행되며 검증과 유효화 검사로 나뉘게 된다. 이 프로세스는 자동차 분야 뿐 아니라 전체적인 개발 진행 과정에서 통용되는 용어로 사전에 설명했던 ISO26262, ASPICE 같은 표준에 들어가는 방법론이다.</p>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/8108daf0-1950-46cd-ad96-a05e39fd5901/image.png" alt=""></p>
<hr>
<h2 id="verification검증">Verification(검증)</h2>
<p>V자 제일 아래있는 Coding 기준으로 왼쪽 부분에 있는 단계들을 Verification. 즉, 검증 단계라고 한다.
(여담으로 정보처리기사 공부할때 배웠던 내용들이 새록새록 기억난다. 그땐 이런게 뭔지 이해가 안가고 왜 배우는지 몰랐지만 현업에 오니 알게 되는구나)</p>
<h4 id="요구사항-분석requirements-analysis">요구사항 분석(Requirements Analysis)</h4>
<ul>
<li>요구사항 분석은 말 그대로 사용자의 필요를 분석해서 정리하는 과정</li>
<li>무엇을 원하는지 기능에 대한 의견을 듣고 문서화</li>
<li>기능적, 물리적, 인터페이서, 성능, 데이터, 보안 요구사항으로 나뉘어 기록</li>
<li>밑그림이 되는 초기 과정이기 때문에 사용자도 문서화한 요구사항들을 잘 확인하고 합의하는 과정이 필요함</li>
</ul>
<h4 id="시스템-설계system-design">시스템 설계(System Design)</h4>
<ul>
<li>고객의 요구사항을 다 확인하고 문서화된 자료를 통해 개발할 시스템에 대해 분석하고 이해함</li>
<li>구현이 불가능하거나 어려운 점이 있다면 사용자와 다시 협의를 통해 요구사항 문서를 수정</li>
<li>이 단계에선 자료구조, 메뉴 구조, 시스템 구성 등 개발에 필요한 소프트웨어 기술서를 작성함</li>
<li>entity diagrams, data dictionary, 시스템 테스트를 위한 문서를 작성하고 전반적으로 공사를 위한 기둥을 세운다고 생각하면 된다</li>
</ul>
<h4 id="아키텍처-설계architecture-design">아키텍처 설계(Architecture Design)</h4>
<ul>
<li>구현할 모듈 항목과 간략한 기능들을 설명하는 설계를하고 그 내용을 문서화 한다</li>
<li>모듈 간의 인터페이스, 관계, 의존성을 기술하고 필요한 데이터베이스 테이블, 아키텍처 다이어그램, 적용기술 내역을 기술한다</li>
<li>통합 테스트에 대한 설계를 함</li>
</ul>
<h4 id="모듈-설계module-design">모듈 설계(Module Design)</h4>
<ul>
<li>아키텍처 설계는 고수준 설계라고하며, 모둘 설계는 저수준 설계라고 부르기도 함</li>
<li>아키텍처 설계에서 정의하고 내용을 설명했던 모듈 항목을 세분해 각각의 모듈에 대한 기술을 작성</li>
<li>프로그래머들이 코딩을 할 수 있도록 함수의 역할과 관계 이름을 만들어 준다고 생각하면 됨</li>
<li>이전 과정에서 처럼 상세하게 문서화하기 보다 의사 코드(pseudocode)를 활용해 기술한다</li>
<li>API 명세를 통해 의존성 관련 이슈와 인터페이스 상세 사항을 기술하고 각 모듈의 에러 코드와 메시지를 기술</li>
<li>모듈의 입력과 출력, 필요한 경우 모듈의 데이터 베이스 테이블의 구조와 요소별 타입과 크기또한 기술함</li>
<li>단위 테스트를 위한 설계를 함</li>
</ul>
<h2 id="coding">Coding</h2>
<ul>
<li>위에서 정의한 요구사항 문서와 시스템 문서, 모듈 문서를 가지고 개발을 진행</li>
</ul>
<h2 id="validation유효화-검사">Validation(유효화 검사)</h2>
<h4 id="단위-테스트unit-testing">단위 테스트(Unit Testing)</h4>
<ul>
<li>V 모델 방식에서 Coding 기준으로 오른쪽에 있는 과정에서 첫 번째이다. 테스트 과정의 시작이라고 보면 됨</li>
<li>앞의 Verification 과정들에서는 고객이 원하는 프로그램을 개발하기 위해 요구사항을 이해하고 시스템 구조를 짜고 내부의 자세한 기능들을 짜면서 큰 틀 -&gt; 작은 틀로 진행됐지만 실질적인 Validation 과정에서는 구현한 함수들의 테스트, 통합 테스트, 시스템 테스트, 인수 테스트와 같은 작은 틀 -&gt; 큰 틀로 진행되는 테스트 단계를 저친다</li>
<li>즉, 단위 테스트는 모듈 설계에서 구현한 모듈들에서 코드가 효율적으로 작성 되었는지 코드 표준을 준수하는지를 검증</li>
<li>모듈 설계 단계에서 준비한 테스트 케이스를 가지고 개발자가 직접 수행하며 화이트박스 테스트라고 불리기도 함</li>
</ul>
<h4 id="통합-테스트integration-testing">통합 테스트(Integration Testing)</h4>
<ul>
<li>각각의 모듈을 통합해 통합된 컴포넌트 간의 인터페이스와 상호 작용 상의 오류를 발견하는 테스트를 진행</li>
<li>블랙박스 테스트를 일반적으로 사용하며 대체로 코드를 직접 확인하지 않음</li>
<li>아키텍처 설계 단계와 연결되며 이 과정에서 준비했던 테스트 케이스를 사용해 테스트를 진행한다</li>
<li>마찬가지로 테스팅은 개발자가 보통 진행</li>
</ul>
<h4 id="시스템-테스트system-testing">시스템 테스트(System Testing)</h4>
<ul>
<li>구현된 시스템과 계획된 사양을 서로 비교하는 작업이 이루어짐</li>
<li>자동화 도구를 이용해 시스템 테스트를 자동화하기도 함</li>
<li>모듈을 통합한 후에 시스템 레벨의 에러들이 여기서 발견될 수 있음</li>
<li>개발자가 아닌 별도의 테스트 팀에 의해 수행됨</li>
<li>자동차 부분에선 차량 제어기를 소프트웨어 팀이 개발하고 성능 검증 팀에서 이 제어기가 어떻게 동작하는지 확인하는 과정과 유사하다고 생각하면 될듯</li>
</ul>
<h4 id="인수-테스트acceptance-testing">인수 테스트(Acceptance Testing)</h4>
<ul>
<li>시스템이나 시스템의 일부 또는 특정한 비기능적인 특성에 대해 확신을 얻는 작업</li>
<li>여러 검색을 통해 내가 이해한 바로는 결함을 찾기 위해 테스트하는 과정이 아닌 시스템을 배포하거나 실제로 사용할만한 준비가 되었는지에 대해 평가하는 과정이다 </li>
<li>고객들의 요구사항과 만들어진 결과물이 일치하고 살제로 배포될 수 있는가를 확인한다 </li>
<li>그림 상에서는 제일 마지막에 있지만 사용자 관점에서 테스팅을 할 수 있고 운영적으로도 테스팅을 진행할 수 있다</li>
</ul>
<hr>
<h2 id="aspice--iso26262">ASPICE &amp; ISO26262</h2>
<h4 id="v-model이-사용되는-파트">V-Model이 사용되는 파트</h4>
<p>ASPICE, ISO26262 둘다 V 모델이 적용이 된다. ASPICE는 차량의 소프트웨어 개발 프로세스를 정의하고 있으며 ISO26262는 전기 전자적인 기능 안전 요건을 정의하고 있다. ASPICE는 아래 그림과 같이 ISO26262의 10파트 중에 6번째 SW Level에 존재한다고 보면 되며 둘다 결과론 적으로 개발 프로세르를 다루기 때문에 V 모델이 적용된다고 보면 된다.</p>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/0b3258b2-8cc7-424b-8df8-1ccb08b8d744/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[ISO 26262 & ASPICE]]></title>
            <link>https://velog.io/@gks970113-woo/ISO-26262-ASPICE</link>
            <guid>https://velog.io/@gks970113-woo/ISO-26262-ASPICE</guid>
            <pubDate>Sun, 07 Jan 2024 09:15:25 GMT</pubDate>
            <description><![CDATA[<p>자동차에 대해 공부를 시작하면서 여러 키워드들을 접하기 시작하고 각각의 관계에 대해서 정리가 어느정도 되기 시작할 즈음 글을 작성한다. 개인적으로 공부하고 적은 내용을 정리해놨기 때문에 틀린 부분이 있을 수도 있다는 점을 참고하면 좋겠다.</p>
<h2 id="iso-26262">ISO 26262</h2>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/52c490ed-bf59-42d5-a4cd-92c9bb6b4c1d/image.png" alt=""></p>
<h3 id="아니-iso가-뭔데">아니 ISO가 뭔데?</h3>
<p>ISO는 International Organization for Standardization, 국제 표준화 기구의 약자이다. 여러 국가의 전문가가 참여해 국제적인 표준을 개발하고, 제품, 서비스, 시스템 및 절차의 품질과 안정성을 향상시켜 규제를 표준화 한다. 말그대로 제품 품질, 환경 관리, 안전, 제조 등 다양한 분야에서 표준을 개발하는 기구라고 생각하면 된다.</p>
<h3 id="이런-기관들이-더-있어">이런 기관들이 더 있어?</h3>
<p>IEC (International Electrotechnical Commission): 전기 및 전자 기술 분야에서의 국제 표준화를 담당
ITU (International Telecommunication Union): 국제 통신에 대한 표준을 제공하는 기관
ASTM International (American Society for Testing and Materials): 미국에서 기반을 둔 ASTM은 건축, 재료, 환경, 의료 등의 분야에서 표준을 제시
IEEE (Institute of Electrical and Electronics Engineers): 전기 및 전자 공학 분야에서의 국제 표준화를 촉진하는 기술 단체로, 전기 및 전자 공학 분야의 다양한 표준을 개발
BSI (British Standards Institution): 영국에서의 표준 개발을 담당하는 기관으로, 다양한 산업 분야에서 표준을 제공
CEN (European Committee for Standardization) 및 CENELEC (European Committee for Electrotechnical Standardization): 유럽에서의 표준화를 담당하는 기관으로, 다양한 산업 분야에서 유럽 표준을 개발
ANSI (American National Standards Institute): 미국에서 표준 개발을 촉진하는 기관으로, 다양한 산업 분야에서 표준을 제공
이런 다양한 분야에서 국제 표준을 개발하고 제시하는 기관들이 많이 존재한다.</p>
<h3 id="iso-26262란">ISO 26262란</h3>
<p>ISO 26262는 ISO 기관에서 제시한 여러 표준 모델 중 자동차 산업에서 사용되는 전기 및 전자 시스템의 기능적 안전성에 관한 국제 표준이다. 총 12개 부문으로 구성되어 있다.</p>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/3ec43cb4-33f5-4622-8693-7d956be052c0/image.png" alt=""></p>
<p>Part1 : 용어(Vocabulary)
Part2 : 기능 안전의 관리(Management of functional safety)
Part3 : 개념 단계(Concept Phase)
<strong>Part4 : 시스템 수준에서 제품 개발(Product development at the system level)
Part5 : 하드웨어 수준 제품 개발(Product development at the Hardware level)
Part6 : 소프트웨어 수준 제품 개발(Product development at the Software level)</strong>
Part7 : 생산 및 운영(Production and operation)
Part8 : 지원 프로세스(Supporting processes)
Part9 : ASIL 중심 및 안전 중심 분석(ASIL-oriented and safety-oriented analyses)
Part10 : ISO26262 가이드라인(Guideline on ISO26262)
Part11 : 반도체 ISO 26262 적용에 대한 가이드라인</p>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/be5522dd-9261-45cb-b6e2-ce529bdcaee8/image.png" alt=""></p>
<p>그림에서 보이는 것과 같이 Part4, 5, 6에서 제품 개발은 모드 V-model을 통해 각 단계와 해당 테스트 단계의 관계를 나타낸다. 제품 개발의 전 단계에서 V-model이 적용된다고 보면 된다. V-model에 대해서는 따로 포스트를 작성해보겠다.</p>
<hr>
<h2 id="aspice">ASPICE</h2>
<h3 id="aspice란">ASPICE란</h3>
<p>Automotive SPICE의 약자로 1990년대 후반 BMW, Bosch, Continental 독일 자동차 회사들이 소프트웨어 개발 프로세스를 평가하고 개선하기 위해 만든 공통 프레임워크이다. 쉽게 이야기해서 ISO26262 처럼 저명한 회사들이 모여 자동차 개발 과정을 정의하고 효율성을 갖추기 위해 표준을 제시했다고 보면 된다. ISO/IEC 15504 표준을 기반으로 한다.</p>
<h3 id="장점">장점</h3>
<p>소프트웨어의 품질 개선 : ASPICE는 소프트웨어 개발 프로세스를 평가 개선하기 위한 표준 프레임워크를 제공하며 비효율성과 결함 오류를 줄이는데 도움을 준다</p>
<p>향상된 효율성 : 미리 정해져 있는 개발 프로세스를 따라가 간소화하고 개발 및 유지 보수 관리에 필요한 시간과 리소스를 효과적으로 줄일 수 있다. 이를 통해 비용을 절감하고 생산성을 높이는 효과를 가져온다</p>
<p>협업 효율 증대 : 공급 업체와 제조 업체간의 협력 과정에서 표준을 가지고 커뮤니케이션을 하기 때문에 서로간의 협업 효율을 증가시킬 수 있는 장점이 있다</p>
<p>고객 만족도 향상 : 우리가 시중에 음식을 먹을때 인증 마크가 있는지 확인하는 것 처럼 자동차도 ASPICE에서 개발한 과정을 지켰다는 것이 확인되면 고객 입장에서 믿고 탈 수 있겠다는 신뢰도가 올라가게 된다</p>
<h3 id="aspice--v-model">ASPICE &amp; V-Model</h3>
<p>검증 및 검증 접근 방식으로 알려진 V-model은 ASPICE가 V-model을 기반으로 구축하는 각 개발 단계에 대한 테스트 단계이다. 요구 사항을 세분화하고 생산 단계마다 테스트를 통해 평가하는 V-model을 기반으로 초기 단계에서 문제를 제거할 수 있고 구체적인 개발 과정을 제시하기 때문에 제조 과정에서 택해지고 있다.</p>
<h3 id="주요-특징">주요 특징</h3>
<p>프로세스 모델 : ASPICE는 소프트웨어 개발 생명 주기의 모든 단계를 다루는 프로세스 모델을 제공한다. 즉, 소프트웨어 개발 과정에서 어떻게 개발을 할지 일련의 과정을 정의해놓은 것이다. 위에서 말한 V-model을 사용하며 요구사항 정의, 시스템 설계, 소프트웨어 설계, 테스트, 유지보수 등의 과정을 가진다.</p>
<p>프로세스 수준 : 이런 개발 과정인 프로세스는 6개의 레벨로 구분되어 있으며 레벨이 올라갈 수록 프로세스의 품질 관리와 능력이 향상된다.</p>
<p>프로세스 평가 및 개선 : ASPICE는 기업이 자체 프로세스를 평가하고 개선할 수 있도록 프로세스 자체에 대한 평가 모델을 제공한다. 레벨 0에서 5까지 정해져있다.</p>
<p>프로세스 영역 : 소프트웨어 개발 및 품질 관리의 여러 영역에 대한 프로세스를 정의하고 있다. </p>
<h3 id="iso26262-vs-aspice">ISO26262 VS ASPICE</h3>
<p>ASPICE와 ISO26262는 모두 자동차 산업에 적용되는 표준이지만 범위와 초점이 다르다. 
ASPICE는 자동차 산업에서 사용되는 소프트웨어 개발 프로세스를 평가하고 개선하기 위한 프레임워크를 제공하는 프로세스 평가 모델이다. 전체 소프트웨어의 개발 수명 주기를 다루고 조직의 프로세스 기능에 중점을 둔다. </p>
<p>ISO26262는 차량 내 전기 전자 시스템의 기능적 안전에 대한 지침을 제공하는 안전 규격이다. 언전 관리, 위험 분석 및 위험 평가, 안전 확인 및 검증에 대한 요구 사항을 지정한다. 이 표준은 차량의 전기 및 전자 시스템 사용과 관련된 안전 위험을 적절하게 관리하고 제어하는 데 중점을 둔다.</p>
<p>즉, ASPICE는 소프트웨어 개발 프로세스와 그 기능에 대한 부분을 중점으로 둔다면 ISO26262는 전기 및 전자 시스템의 안전과 관련된다. 자동차를 개발할 때 두 표준을 다 준수해야한다고 생각하면 된다.</p>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/59e96f94-f5b7-4c94-a9a6-5838d797e2f9/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[c/c++] Softeer 수퍼바이러스 Lv3]]></title>
            <link>https://velog.io/@gks970113-woo/cc-Softeer-%EC%88%98%ED%8D%BC%EB%B0%94%EC%9D%B4%EB%9F%AC%EC%8A%A4-Lv3</link>
            <guid>https://velog.io/@gks970113-woo/cc-Softeer-%EC%88%98%ED%8D%BC%EB%B0%94%EC%9D%B4%EB%9F%AC%EC%8A%A4-Lv3</guid>
            <pubDate>Thu, 02 Nov 2023 14:49:19 GMT</pubDate>
            <description><![CDATA[<p>현대오토에버 코딩테스트 대비 오랜만에 감을 살리려고 처음으로 소프티어에 있는 문제들을 풀어봤다 대체로 Lv3 정도의 난이도가 나온다고해서 나와있는 문제들은 한번 다 풀어보려고 한다.</p>
<p>문제들이 대체로 어렵진 않은 것 같은데 정확한 설명이 부족하고 2프로 아쉬운느낌..?
그래도 함정이 조금 있어서 잘 생각해봐야한다.</p>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/4d74f9a3-75b0-4c83-896a-c912b6bca3dc/image.png" alt=""></p>
<p>완전 탐색으로 풀려고 그냥 처음부터 반복문으로 단순히 하려다가 실패
단위가 굉장히 크기 떄문에 long long 자료형을 사용하고 분할정복으로 각 연산 단위를 줄여줘야한다. 전체적으로 계산량 자체는 많지 않기 때문에 재귀를 사용해도 적합한 문제였다.</p>
<pre><code class="language-cpp">#include&lt;iostream&gt;

#define mod 1000000007;

using namespace std
long long K, P, N;

long long calc(long long count){
  if(count == 1)
    return P;
  long long result = calc(count/2);
  result = result * result % mod;
  if(count%2==1)
    result = (result * P) % mod;
  return result;
}

int main(int argc, char** argv)
{
  cin &gt;&gt; K &gt;&gt; P &gt;&gt; N;
  cout &lt;&lt; (calc(N*10) * K) % mod;
  return 0;
}</code></pre>
<p>int, long long 같은 자료형의 범위를 확실하게 정리해서 c++ 코너에 정리해놔야겠다 문자열을 쓰려고도 했었다 헷갈린다 ㅎ</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[내가 보려고 만든 C++ 정리]]></title>
            <link>https://velog.io/@gks970113-woo/%EB%82%B4%EA%B0%80-%EB%B3%B4%EB%A0%A4%EA%B3%A0-%EB%A7%8C%EB%93%A0-C-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@gks970113-woo/%EB%82%B4%EA%B0%80-%EB%B3%B4%EB%A0%A4%EA%B3%A0-%EB%A7%8C%EB%93%A0-C-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Thu, 02 Nov 2023 06:58:47 GMT</pubDate>
            <description><![CDATA[<h2 id="반올림-올림-내림">반올림, 올림, 내림</h2>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;cmath&gt;
//header

using namespace std;

int main() {
    float a;
    float b;
    float c;

    a = ceil(5.1);
    b = floor(2.8);
    c = floor(3.2 + 0.5);

    cout &lt;&lt; a &lt;&lt; endl;
    cout &lt;&lt; b &lt;&lt; endl;
    cout &lt;&lt; c &lt;&lt; endl;
}
</code></pre>
<p>결과</p>
<pre><code>6
2
3</code></pre><p>반올림 전용 round 함수가 있지만 c++ 11 버전부터 지원하기 때문에
반올림하려는 수에 0.5를 더해 floor 내림 함수를 이용해서 반올림하는 습관을 키우자</p>
<hr>
<h2 id="n번째-소수점-다루기반올림-올림">n번째 소수점 다루기(반올림, 올림)</h2>
<p>문제에서 간혹가다가 소수점 n번째에서 반올림하거나 올림, 내림하는 문제가 있다. ceil, floor, round 함수는 소수점 첫째자리에서 실행되어 정수를 반환하기 때문에 원하는 n번째 자리에서 반올림하고 싶으면 곱한뒤에 반올림을 실행해야한다.</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;cmath&gt;
//header

using namespace std;

int main() {
    float num = 5.12345;

    float rounded = floor(num * 100.0 + 0.5) / 100.0; // 반올림하여 소수점 두 자리까지

    cout &lt;&lt; fixed &lt;&lt; setprecision(2) &lt;&lt; rounded &lt;&lt; endl; // 고정된 소수점 두 자리 출력
}</code></pre>
<hr>
<h2 id="fixed-setprecision">fixed, setprecision</h2>
<p>setprecision만 사용하면 예를 들어 a = 3.141592 라는 수가 있을때
cout &lt;&lt; setprecision(3) &lt;&lt; a;</p>
<pre><code>3.14</code></pre><p>3.14가 출력된다 소수점 포함 3자리까지만 출력이 된다
그런데 cout &lt;&lt; fixed &lt;&lt; setprecision(3) &lt;&lt; a;</p>
<pre><code>3.141</code></pre><p>했을때는 정수 부분을 카운트하지 않고 소수 부분 3자리까지 출력이된다</p>
<p>예시 문제</p>
<p><a href="https://softeer.ai/practice/6294">소프티어 연습문제 성적 평균 Lv3</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Dubins Path Algorithm]]></title>
            <link>https://velog.io/@gks970113-woo/Dubins-Path-Algorithm</link>
            <guid>https://velog.io/@gks970113-woo/Dubins-Path-Algorithm</guid>
            <pubDate>Fri, 11 Aug 2023 04:56:39 GMT</pubDate>
            <description><![CDATA[<h1 id="dubins-path-algorithm">Dubins Path Algorithm</h1>
<p>Dubins Path 알고리즘은 로봇이나 차량과 같은 이동체가 제한된 반경 내에서 움직일 때 최적의 경로를 계획하는 알고리즘
이동체의 회전 반경과 가능한 직진 거리의 제약 조건을 고려해 경로를 생성한다
로봇이 갈 수 있는 경로를 미리 계산(offline)
미리 계산된 경로를 이용하여 경로 planning(online)</p>
<h2 id="dubins-path-장점">Dubins Path 장점</h2>
<ul>
<li>최소한의 회전을 사용해 경로를 계획한다. 회전 능력을 최대한 활용해서 목표 지점에 빠르게 도착</li>
<li>간단한 수학 모델을 사용하기 때문에 구현이 어렵지 않다</li>
<li>회전 반경과 직진 거리 제약 조건을 고려해 실제 환경의 이동체의 제약을 잘 반영</li>
<li>미리 계산된 경로로 탐색을 하기 때문에 연산 속도가 매우 빠름</li>
</ul>
<h2 id="단점">단점</h2>
<ul>
<li>높은 속도로 이동하거나 복잡한 환경에서 적합하지 않음</li>
<li>경로 길이가 너무 긴 경우 정확도가 떨어질 수 있음</li>
<li>모든 경우를 미리 계산해놓을 수 없기 때문에 완벽한 최단 루트를 구하기 어려움</li>
</ul>
<h2 id="motion-primitives">Motion primitives</h2>
<ul>
<li>Dubins Path 에선 Motion primitives를 사용</li>
<li>간단한 움직임 패턴이나 동작을 나타내며 정해진 패턴을 합쳐서 복잡한 루트를 생성한다</li>
<li>직진, 좌회전, 우회전과 같은 기본 움직임을 Motion primitives로 사용해서 주차하거나 자율주행에 사용하도록 경로를 생성하고 제어할 수 있다</li>
</ul>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/336f78f3-4a15-477d-9a48-ffc353159a73/image.png" alt=""></p>
<h3 id="vehicle-model">Vehicle model</h3>
<ul>
<li>State : x, y, θ</li>
<li>Input : curvature u(steering)</li>
</ul>
<p>x&#39; = cosθ
y&#39; = sinθ
θ&#39; = u
(&#39;) = d/dX</p>
<h3 id="six-words">Six words</h3>
<p>{LRL, RLR, LSL, LSR, RSL, RSR}</p>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/d0cbec17-9844-4b86-a6ff-62c8748aafd5/image.png" alt=""></p>
<p>위처럼 6가지 루트가 존재하는데 </p>
<ol>
<li>각 시작 점을 기준으로 원을 그림</li>
<li>벡터에서 왼쪽에 원이 존재하면 L, 오른쪽이면 R</li>
<li>왼쪽, 오른쪽으로 돌고 직진하면 S 오른쪽으로 가거나 왼쪽으로 가면 R, L</li>
<li>이동한 방향에 맞게 LRL, RLR, LSL, LSR, RSL, RSR 중 정함</li>
<li>각 θ값은 초록색처럼 정함</li>
</ol>
<h4 id="기본-구현">기본 구현</h4>
<pre><code class="language-cpp">
class DubinsPath(object):
    def __init__(self, t=0, p=1e10, q=0, type=None):
        self.t = t
        self.p = p
        self.q = q
        self.length_ = [t, p, q]
        self.type = type
        self.controls = None

    def length(self):
        return self.t + self.p + self.q</code></pre>
<h4 id="lsl">LSL</h4>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/f76a69c3-428b-4cf2-b04f-999bd9e53f2e/image.png" alt=""></p>
<h4 id="rsr">RSR</h4>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/67112bb4-2904-41ee-93b8-2df370453d33/image.png" alt=""></p>
<h4 id="rsl">RSL</h4>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/32598898-6c09-4106-b0de-32b08b31c8f5/image.png" alt=""></p>
<h4 id="lsr">LSR</h4>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/2aca26b9-4d5f-4455-9d3e-547692943517/image.png" alt=""></p>
<h4 id="rlr">RLR</h4>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/25c054f2-8aac-4d2f-9143-133b234d7c23/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/cad611c1-a9bf-40b5-bbba-e01b0fc017cd/image.png" alt=""></p>
<h4 id="lrl">LRL</h4>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/b688a603-5d9b-492e-9d61-983d853d8290/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[SLAM의 종류]]></title>
            <link>https://velog.io/@gks970113-woo/SLAM%EC%9D%98-%EC%A2%85%EB%A5%98</link>
            <guid>https://velog.io/@gks970113-woo/SLAM%EC%9D%98-%EC%A2%85%EB%A5%98</guid>
            <pubDate>Fri, 14 Jul 2023 09:34:18 GMT</pubDate>
            <description><![CDATA[<h2 id="visual-slamvslam">Visual SLAM/VSLAM</h2>
<p>visual 정보를 사용하는 SLAM</p>
<p>장점</p>
<ul>
<li>저렴한 센서를 사용</li>
<li>센서의 성능을 조절하기 쉬움(ex 렌즈교체 - 시야각, 초점 조절, 노출 시간)</li>
<li>이미지 기반 딥러닝 적용 가능 - Object detection / segmentation</li>
<li>이미지로 사람이 이해하기 쉬운 시각화 기능</li>
</ul>
<p>단점</p>
<ul>
<li>갑작스러운 빛 변화에 대응 불가능</li>
<li>시야가 가려지거나 어두운 곳에서 사용 불가능</li>
</ul>
<p>Camera = Camera device + Lens</p>
<p>Camera configuration</p>
<ul>
<li>RGB camera</li>
<li>Grayscale camera</li>
<li>Multi-spectral camera</li>
<li>Polarized camera</li>
<li>Event camera</li>
</ul>
<p>Lensconfiguration</p>
<ul>
<li>Perspective camera</li>
<li>Wide FOV camera</li>
<li>Telecentric camera</li>
<li>Fisheye camera</li>
<li>360 degree camera</li>
</ul>
<p>Type of camera configuration</p>
<ul>
<li>Monocular camera - 1 camera</li>
<li>Stereo camera - 2 camera/Multi camera - N cameras</li>
<li>RGB-D camera(Depth camera)</li>
</ul>
<h3 id="monocular-vslam">Monocular VSLAM</h3>
<p>특징</p>
<ul>
<li>1대의 카메라에서만 이미지를 받음</li>
<li>(연구용 알고리즘이라는 인식이 있음)</li>
</ul>
<p>장점</p>
<ul>
<li>Stereo / Multi camera VSLAM 보다 저렴함 (센서 가격, 전력 소비량, 이미지 데이터 송수신 대역폭)</li>
</ul>
<p>단점</p>
<ul>
<li>Scale ambiguity - 3D 공간을 실제 스케일로 추정할 수가 없다(up-to-scale 로만 추정 가능)</li>
<li>이 문제를 풀기 위해선 metric scale을 가진 proprioceptive sensor가 필요</li>
<li>최근 딥러닝 기반 monocular depth estimation으로 문제를 해결하려는 시도가 있음</li>
</ul>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/6f4ec573-65d2-4c1c-a83c-610d4de09c29/image.png" alt=""></p>
<h3 id="stereo--multi-camera-vslam">Stereo / Multi camera VSLAM</h3>
<p>특징</p>
<ul>
<li>Stereo - 2대의 카메라를 사용</li>
<li>Multi-camera - N대의 카메라 사용</li>
<li>민첩한 카메라들간의 baseline 거리를 이용하여 삼각측량을 통해 거리/길이 추정 가능</li>
</ul>
<p>장점</p>
<ul>
<li>두 이미지 간의 disparity 정보를 이용해서 픽셀마다 depth를 추정할 수 있음</li>
<li>Metric scale의 3D 공간을 복원 가능</li>
</ul>
<p>단점</p>
<ul>
<li>카메라 설정 및 캘리 브레이션이 어려움<ul>
<li>모든 카메라는 동시에 이미지를 취득해야함</li>
<li>Baseline이 충분히 길어야 먼 거리의 3D 공간을 정확하게 측정할 수 있음</li>
<li>카메라 들 마다 intrunsic/Extrinsic 캘리브레이션을 정확하게 해야함. 이 과정이 거의 불가능에 가깝기도 하다</li>
</ul>
</li>
<li>모든 픽셀마다 disparity 정보로 depth를 계산하는데에는 많은 계산량이 필요하며 이를 위해 GPU나 FPGA 계산이 요구되기도 함</li>
</ul>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/a09b2763-51f4-4c52-855d-a1fcf6b07323/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/d8e4eaa7-4a87-4e38-b8ef-43f224fa0070/image.png" alt=""></p>
<h3 id="rgb-d-vslam">RGB-D VSLAM</h3>
<p>Structured light(구조광), 또는 Time-of-Flight(ToF) 센서를 이용한 카메라를 사용
센서가 Depth 값을 직접 얻어주기 때문에 계산이 필요하지 않음
Dense mapping을 많이 하는 편</p>
<p>장점</p>
<ul>
<li>Depth 데이터를 통해 3D 공간을 metric scale로 실시간 복원 가능</li>
</ul>
<p>단점</p>
<ul>
<li>~10m 정도에서만 depth 데이터가 정확함</li>
<li>Field of view가 작용</li>
<li>실외에서 사용 불가(적외선 파장이 햇빛과 간섭)</li>
</ul>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/d829bb57-9de9-4e76-9154-793fd2659dcb/image.png" alt=""></p>
<h2 id="lidar-slam">LIDAR SLAM</h2>
<p>LIDAR 정보를 이용한는 SLAM
Exteroceptive senso = LIDAR</p>
<h2 id="radar-slam">RADAR SLAM</h2>
<p>RADAR 정보를 이용하는 SLAM
Exteroceptive sensor = RADAR</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Localization을 위한 센서]]></title>
            <link>https://velog.io/@gks970113-woo/Localization%EC%9D%84-%EC%9C%84%ED%95%9C-%EC%84%BC%EC%84%9C</link>
            <guid>https://velog.io/@gks970113-woo/Localization%EC%9D%84-%EC%9C%84%ED%95%9C-%EC%84%BC%EC%84%9C</guid>
            <pubDate>Fri, 14 Jul 2023 07:43:43 GMT</pubDate>
            <description><![CDATA[<h2 id="proprioceptive-sensors">Proprioceptive sensors</h2>
<ul>
<li>자기 자신의 움직임을 감지하는 센서</li>
</ul>
<h3 id="imu">IMU</h3>
<p>Intertial measurement unit</p>
<ul>
<li>Linear acclerator(선형 가속도 측정)센서와 Angular gyroscope(각속도 측정) 센서가 혼합된 센서</li>
<li>Spring-damper system의 원리를 이용</li>
<li>Optical system - 차랑용IMU</li>
<li>MEMS - 스마트폰 및 소형 디바이스 IMU</li>
</ul>
<p>장점</p>
<ul>
<li>Computer grade 제품은 저렴한 편(자동차는 동일 성능에 저렴하지 않음)</li>
<li>높은 sensitivity</li>
<li>높은 FPS(100~4000HZ)</li>
</ul>
<p>단점</p>
<ul>
<li>엄청나게 빠른 drift 누적</li>
<li>보정을 위해 Camera/LIDAR/GNSS 와 함께 사용</li>
</ul>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/98256658-d548-485e-b1ff-6753f75c264d/image.png" alt=""></p>
<h3 id="wheel-encoder">Wheel encoder</h3>
<p>바퀴의 회전량 (RPM)과 이동량(=바퀴의 회전량 * 바퀴의 둘레)을 측정하는 센서</p>
<p>장점</p>
<ul>
<li>자동차에는 기본적으로 탑재</li>
<li>로봇, 드론 자율주행에도 제어를 위해 센서가 탑재되어 있음</li>
<li>자동차의 위치추정을 위한 Dead Reckoning 알고리즘에 많이 사용됨</li>
</ul>
<p>단점</p>
<ul>
<li>Odometry를 할 시 drift에 약함</li>
<li>바퀴가 헛도는 경우 잘못된 센서의 값이 생길 수 있음</li>
<li>바퀴의 둘레가 주행 중 자주 바뀜(탑승자의 무게, 코너링, 바람빠짐, 마찰열로 인한 타이어 팽창 등)</li>
</ul>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/bface33e-7e75-426f-9e77-a3851f86190b/image.png" alt=""></p>
<hr>
<h2 id="exteroceptive-sensors">Exteroceptive sensors</h2>
<ul>
<li>외부의 움직임을 감지하는 센서</li>
</ul>
<h3 id="gnss">GNSS</h3>
<p>Global navigation satellite system
비콘 기반의 위치 추정 센서</p>
<p>다수의 비콘에 대한 통신시간 차이를 이용하여 비콘-로봇의 거리를 구하고, 삼각측량을 통해 Localization 수행
Ego-motion을 추정하기 때문에 proprioceptive sensor 같지만, 외부 비콘을 이용하기 때문에 exteroceptive sensor임</p>
<p>나라마다 시스템이 다르다</p>
<ul>
<li>GPS(USA), GLONASS(Russia), BeiDou(China), Gallileo(Europe), KPS(Korea - 2035 목표)</li>
</ul>
<p>장점</p>
<ul>
<li>싸고 사용하기 쉬움</li>
</ul>
<p>단점</p>
<ul>
<li>부정확함(10~20m 오차)</li>
<li>RTK-GPS, DGPS를 사용할 경우 오차는 cm 단위로 내려옴(가격이 억대임)</li>
<li>고층빌딩 사이에서 multi-path 문제</li>
<li>실내/지하 사용 불가능</li>
<li>KPS가 아직 없다</li>
</ul>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/7582105b-a82f-49aa-a7ed-8d5e15f1fe3b/image.png" alt=""></p>
<blockquote>
<p>이미지 출처 : <a href="https://www.everythingrf.com/community/what-is-the-difference-between-gnss-and-gps_58">https://www.everythingrf.com/community/what-is-the-difference-between-gnss-and-gps_58</a></p>
</blockquote>
<h3 id="uwb-beacon">UWB Beacon</h3>
<p>GPS와 상당히 유사함</p>
<ul>
<li>사용 환경에 Beacon 설치 + Beacon과의 소통을 통해 위치 추정</li>
</ul>
<p>장점</p>
<ul>
<li>cm 단위의 정밀도로 위치를 추정할 수 있음</li>
<li>타 무선 신호로부터의 간섭에 강함</li>
</ul>
<p>단점</p>
<ul>
<li>특정 재질의 벽에 신호가 막힐 수 있음</li>
<li>전력 소모가 높음</li>
<li>다수의 수신기를 설치해줘야함</li>
<li>장거리에서는 동작이 어려움</li>
</ul>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/c42a895e-0828-41bd-8c5e-7d28d9878a37/image.png" alt=""></p>
<h3 id="motion-capturemo-cap">Motion capture(Mo-cap)</h3>
<p>적외선 레이저와 반사 마커를 이용해 위치를 추정하는 시스템</p>
<p>장점</p>
<ul>
<li>mm단위의 고정밀 위치 추정이 가능</li>
<li>고성능 시스템의 경우 120+FPS로의 위치 추정이 가능</li>
</ul>
<p>단점</p>
<ul>
<li>다수의 고가 카메라를 설치해야함</li>
<li>특정 각도에서 반사 마커가 가려지는 경우 위치 추정이 어려울 수 있음</li>
</ul>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/47990e3a-009f-4b2b-8159-8916d9053a2f/image.png" alt=""></p>
<h3 id="lidarlight-detection-and-ranging-sensors">LIDAR(Light detection and ranging sensors)</h3>
<p>적외선 레이저를 쏘고 반사 시간을 측정하여 거리를 추정하는 센서</p>
<ul>
<li>Time-of-flight(ToF), Phase shift, Frequency modulation 레이저 방식</li>
<li>Mechanical scanner, Solid state scanner, Flash LIDAR 스캐닝 방식
주변 환경을 3D point cloud 형태로 바로 알 수 있음</li>
</ul>
<p>장점</p>
<ul>
<li>Exteroceptive 센서 중 가장 정확한 편</li>
<li>자율 주행을 라이다는 100m 유효거리 가짐</li>
<li>빛의 파장이 일어나지 않기 때문에 낮/밤 사용 가능</li>
<li>동일한 device로 인한 간섭 제외</li>
</ul>
<p>단점</p>
<ul>
<li>비싸다</li>
<li>카메라에 비해 resolution이 낮음</li>
<li>눈/비/안개 등 날씨의 영향을 받음</li>
<li>Multi-path 문제</li>
<li>Solid-state LIDAR의 경우 여러 방향으로 탑재 필요</li>
<li>동일한 제품군의 라이다 레이저가 겹치면 문제 발생</li>
<li>가까운 거리의 물체의 밀도는 높게 멀리있는 물체의 밀도는 낮게 나와 알고리즘 설계 어려움</li>
<li>고여있는 물웅덩이나 반사판에 의해 잘못된 측정 가능</li>
</ul>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/9a1061b8-232a-4664-a743-541fe686033a/image.png" alt=""></p>
<h3 id="radarradio-detection-and-ranging-sensor">RADAR(Radio detection and ranging sensor)</h3>
<p>반사되어 돌아오는 전파를 측정하여 radial 거리를 재는 센서
Doppler 효과를 이용해 이동중인 물체의 속도 추정 가능
전파의 종류를 바꿈으로써 near-range와 far-range 선택 가능</p>
<p>장점</p>
<ul>
<li>날씨 영향 X</li>
<li>타 센서에서는 얻지 못하는 속도 값 추정 가능</li>
<li>에러들만 처리해주면 아주 좋은 센서</li>
</ul>
<p>단점</p>
<ul>
<li>작은 물체들은 detection 실패</li>
<li>LIDAR 보다 낮은 resolution</li>
<li>Multi-path 문제</li>
</ul>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/84e496c6-f39a-4dd0-8e65-c8e597f3ec2f/image.png" alt=""></p>
<h3 id="ultrasound">Ultrasound</h3>
<p>초음파를 이용 - RADAR와 동일</p>
<p>장점</p>
<ul>
<li>저렴함</li>
<li>Near-range에서 잘 적용됨</li>
</ul>
<p>단점</p>
<ul>
<li>물체의 형태를 잘 추정하지 못함</li>
<li>그렇기 때문에 Distance 센서로 활용</li>
<li>노이즈가 많다</li>
</ul>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/381f3a76-2bc1-4d6b-a480-edd12cbc06fd/image.png" alt=""></p>
<h3 id="camera">Camera</h3>
<p>광센서를 이용해 빛 신호를 받고, debayering 프로세스를 통해 RGB 색 재구성</p>
<p>장점</p>
<ul>
<li>저렴함</li>
<li>좋은 성능 - Dense data, Texture, Color, High-FPS</li>
<li>렌즈 교환을 통해 시야각 연장 가능</li>
<li>사람이 보는 시야와 가장 유사함</li>
<li>시각화를 하기 가장 좋은 데이터이다</li>
</ul>
<p>단점</p>
<ul>
<li>Depth 정보 소실</li>
<li>조명 영향</li>
</ul>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/4d83e20b-33ac-4c2e-b955-0108164d818f/image.png" alt=""></p>
<h3 id="camera--fiducial-marker인위적으로-만든-패턴-마커">Camera + Fiducial Marker(인위적으로 만든 패턴 마커)</h3>
<p>Fiducial marker를 바라보고 있을 때, 카메라의 위치를 추정하는 방법</p>
<ul>
<li>Fiducial marker의 크기를 알고 있어야 함</li>
</ul>
<p>장점</p>
<ul>
<li>저렴함</li>
<li>증강현실(로보틱스 용도)로 쓰기 적합</li>
</ul>
<p>단점</p>
<ul>
<li>다수의 Fiducial marker를 설치/관리 해야함</li>
<li>조명의 영향을 받음</li>
<li>외부적인 요인에 의해 Marker가 훼손 될 수 있음</li>
</ul>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/57842e0a-758c-4ab0-b522-51c4033ca61e/image.png" alt=""></p>
<blockquote>
<p>이미지 출처 : <a href="https://www.tangramvision.com/blog/reverse-engineering-fiducial-markers-for-perception">https://www.tangramvision.com/blog/reverse-engineering-fiducial-markers-for-perception</a></p>
</blockquote>
<h3 id="적외선-camera--reflective-marker">적외선 Camera + Reflective marker</h3>
<p>천장에 부착된 반서 마커를 바라보고 있을 때, 적외선 카메라의 위치를 추정하는 방법</p>
<ul>
<li>적외선은 IR emitter을 통해 방출함</li>
<li>서빙로봇에서 많이 사용됨</li>
</ul>
<p>장점</p>
<ul>
<li>조명 변화에 민감</li>
<li>증강현실(로보틱스 용도)로 쓰기 적합함</li>
</ul>
<p>단점</p>
<ul>
<li>다수의 Fiducial marker를 설치/관리 해야함</li>
</ul>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/7cab125b-34d3-41ce-8308-f5cd60413177/image.png" alt=""></p>
<blockquote>
<p>이미지 출처 : <a href="https://schulich.ucalgary.ca/labs/position-location-and-navigation/files/position-location-and-navigation/lakhani2013_conference_a.pdf">https://schulich.ucalgary.ca/labs/position-location-and-navigation/files/position-location-and-navigation/lakhani2013_conference_a.pdf</a></p>
</blockquote>
<h3 id="microphones">Microphones</h3>
<p>공기의 진동을 transducer 센서를 통해 전기 신호로 변환하는 센서
여러개의 마이크를 통해 소리의 근원에 대한 위치를 계산 가능</p>
<p>장점</p>
<ul>
<li>유일하게 소리 정보를 사용하는 센서</li>
<li>저렴한 가격</li>
</ul>
<p>단점</p>
<ul>
<li>Geometry가 부정확함(위치 추정이 쉽지 않음)</li>
<li>잡음이 심함</li>
<li>사용자가 없음</li>
</ul>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/1f39fe25-22b0-40d3-8cf6-12d869e138f1/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[SLAM의 개요]]></title>
            <link>https://velog.io/@gks970113-woo/SLAM</link>
            <guid>https://velog.io/@gks970113-woo/SLAM</guid>
            <pubDate>Fri, 14 Jul 2023 04:05:04 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/562a8c64-5b58-41cb-9b4b-6898f1cf4780/image.png" alt=""></p>
<blockquote>
<p>이미지 출처 : <a href="https://kr.mathworks.com/discovery/slam.html">https://kr.mathworks.com/discovery/slam.html</a></p>
</blockquote>
<h4 id="simulatneous-localization-and-mapping">Simulatneous Localization and Mapping</h4>
<p>동시적 위치 추정 및 지도 작성</p>
<ul>
<li>위치 정보와 지도 정보가 아예 없는 불완전한 환경에서 사용이 가능</li>
<li>SLAM을 통해 최적의 위치 정보를 추론 가능</li>
<li>자율주행 차량에 사용되어 주변 환경 지도를 작성하는 동시에 차량의 위치를 지도 안에서 인식하는 기법</li>
</ul>
<h4 id="localizaiton">Localizaiton</h4>
<ul>
<li>정확한 지도 정보를 기반으로 위치 정보를 알아내는 기술</li>
<li>GPS 처럼 네비게이션에서 내 위치에 대한 위도, 경도, 고도, 좌표를 가져 오는 것 처럼 내 위치를 추정하는 과정</li>
<li>내가 어디 있는지 추론하는 과정</li>
</ul>
<h4 id="mapping">Mapping</h4>
<ul>
<li>정확한 위치 정보를 기반으로 지도를 그리는 기술</li>
<li>정확한 지도가 있어야 내가 어디 있는지 잘 알 수가 있음</li>
</ul>
<h4 id="monte-carlo-localization">Monte Carlo Localization</h4>
<ul>
<li>지도가 사전 정보로 주어졌을때 particle filter를 이용해서 현재 위치를 추론하는 방법</li>
<li>모든 지도에 내 위치 정보가 흩뿌려지고 움직이며 주변 환경과 비교해서 위치할 수 없는 곳의 위치 정보들은 없어지고 위치할 가능성이 높은 정보만 남는 알고리즘</li>
</ul>
<p>단점</p>
<ul>
<li>지도가 정확하지 않으면 내 위치를 추론하는데 어려움이 있음</li>
<li>지도 내에 비슷한 공간이 존재하고 내 위치가 그쪽에 있다면 정확한 추론이 어려움</li>
<li>지도가 없다면 내 위치를 추론할 수 없음</li>
</ul>
<h4 id="chiken-and-egg-problem">Chiken and Egg problem</h4>
<ul>
<li>닭이 먼저인지 달걀이 먼저인지 문제처럼 지도가 먼저일지 위치 정보가 먼저일지 고민이 있음</li>
<li>Localization과 Mapping은 각자 서로의 믿을 수 있는 정보가 있어야 정확히 추론할 수 있음</li>
<li>이를 해결하기 위해서 동시적 위치 추정 및 지도를 작성하는 SLAM이 나오게 됨</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[OpenCV_2)]]></title>
            <link>https://velog.io/@gks970113-woo/OpenCV2</link>
            <guid>https://velog.io/@gks970113-woo/OpenCV2</guid>
            <pubDate>Sat, 20 May 2023 17:41:20 GMT</pubDate>
            <description><![CDATA[<p>OS support : Window, Linux, MacOS, iOS, Android
Language : C, C++, Java, Python</p>
<p>OpenCV가 동작하기 위해선
소스 형태 File</p>
<ul>
<li>헤더 소스 File</li>
<li>사전에 학습된 사물인식 설정File</li>
</ul>
<p>이진형태 file</p>
<ul>
<li>라이브러리(실행 시)</li>
<li>라이브러리 (컴파일 및 링크시)</li>
<li>동영상 디코더 라이브러리</li>
</ul>
<p>개발 환경에서 설정해주는 사항(공통)</p>
<ul>
<li>openCV용 include 파일들의 경로 : include/opencv/opencv2/opencv.hpp</li>
<li>소스 파일을 가져와 직접 컴파일, 링크해서 라이브러리를 이진파일로 만들기(Linux에서 적용)</li>
</ul>
<p>윈도우에서는 Visual Studio와 openCV를 다운받아서 같이 사용해줘야함
그러나 나는 Linux 환경에서 ROS에 작동시킬 거라 visual studio는 받지 않고 진행하겠다</p>
<hr>
<h2 id="mat">Mat</h2>
<p>OpenCV에서 하나의 이미지를 기본으로 표현하는 자료구조
Mat은 header와 채널이 몇개인지 정보가 담겨있음</p>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/91b5f40d-c24d-49b5-bbfe-1f214ed23303/image.png" alt=""></p>
<ul>
<li>채널의 순서는 특이하게 RGB순이 아니라 RBG순이다</li>
</ul>
<h4 id="행렬-원소-자료형">행렬 원소 자료형</h4>
<p>Mat Class는 int, float, double, char, short(unsigned 포함)의 자료형을 지원한다. 이 정보를 Depth라고 일컫으며 다음과 같이 표현할 수 있다</p>
<ul>
<li>CV_8U: 8-bit unsigned integers (0 to 255)</li>
<li>CV_8S: 8-bit signed integers (-128 to 127)</li>
<li>CV_16U: 16-bit unsigned integers (0 to 65535)</li>
<li>CV_16S: 16-bit signed integers (-32768 to 32767)</li>
<li>CV_32S: 32-bit signed integers (-2147483648 to 2147483647)</li>
<li>CV_32F: 32-bit floating-point numbers</li>
<li>CV_64F: 64-bit floating-point numbers</li>
</ul>
<p>ex1) CV_8UC3 : 3개의 채널을 가지고 8-bit의 픽셀을 각각 가지고 있다
ex2) CV_8UC1 : 싱글 채널을 가지고 8-bit의 픽셀을 가지고 있다</p>
<h4 id="초기화">초기화</h4>
<pre><code class="language-cpp">cv::Mat M;
//빈 행렬 객체 M 생성
cv::Mat M(rows, colums, pixel_type);
//열, 행, 픽셀 타입을 가지는 객체 M 초기화
cv::Mat M(rows, colums, pixel_type, initial_value);
cv::Mat M(Size(width, height), pixel_type, initial_value);
</code></pre>
<h4 id="예제">예제</h4>
<pre><code class="language-cpp">cv::Mat M;
// 빈 행렬 생성
cv::Mat M(3, 3, CV_32F, cv::Scalar(0));
// 3x3 크기의 행렬을 생성, 타입은 32비트 실수형 (0으로 초기화)
float data[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
// 실수형태의 배열 data
cv::Mat M(3, 3, CV_32F, data);
// M 값 데이터 직접 넣어서 행렬 생성해주기


Mat_&lt;float&gt; mat_(2,3);
mat_ &lt;&lt; 1, 2, 3, 4, 5, 6;
Mat mat = mat_;</code></pre>
<h4 id="mat-size">Mat Size</h4>
<p>Mat 객체의 사이즈(bits) = colums * rows * channels * channel depth</p>
<p>ex) Mat M(10, 15, CV_8UC3)의 크기 = 10 rows * 20 cols * 3ch/pixel * 8 bits/ch = 4800bits</p>
<p>Mat.elemSize1()</p>
<ul>
<li>한 픽셀의 채널 당 바이트수</li>
<li>위의 예제에서는 3개의 채널이고 1픽셀이 8bit를 가진다 8bit은 2byte니까 2를 반환한다</li>
</ul>
<p>Mat.elemSize()</p>
<ul>
<li>한 픽셀 당 바이트 수의 채널을 곱한 값</li>
<li>위의 예제는 한 픽셀이 8bit의 크기를 가지면서 3개의 채널로 구성되어 있으니 24를 4로 나눈 6을 반환한다</li>
<li>elemSize1(), elemSize() 모두 데이터 타입은 값의 영향을 미치지 않고 한 픽셀이 몇바이트의 값을 가지고 채널이 몇개인지만 신경써주면 된다</li>
</ul>
<hr>
<h4 id="이미지-처리-함수">이미지 처리 함수</h4>
<p>imread()</p>
<ul>
<li>cv::imread(const String&amp; filename, int flags = IMREAD_COLOR)</li>
<li>이미지 파일을 읽는 함수</li>
<li>첫 번째 인자는 이미지 파일의 경로, 두 번째 인자는 이미지를 어떻게 읽을지를 결정하는 플래그</li>
<li>이미지 파일의 경로가 &quot; &quot;형태라면 상대 경로로 지정이 되어있는데 경로는 환경마다 다르다. xcode에서는 직접 workspace를 정해주고 window의 visual studio 같은 경우는 project 폴더로 지정이 되어있다한다</li>
<li>flags 변수는 0, 1, -1이 될 수 있다. 0은 흑백 이미지, 1은 컬러 이미지, -1은 원본 이미지이다 </li>
</ul>
<p>imwrite()</p>
<ul>
<li>cv::imwrite(const String&amp; filename, InputArray img, const std::vector<int>&amp; params = std::vector<int>())</li>
<li>이미지 파일을 쓰는 함수</li>
<li>첫 번째 인자는 저장할 파일의 경로이며, 두 번째 인자는 저장할 이미지이다</li>
</ul>
<p>imshow()</p>
<ul>
<li>cv::imshow(const String&amp; winname, InputArray mat)</li>
<li>이미지를 화면에 표시하는 함수. 첫 번째 인자는 창의 이름이며, 두 번째 인자는 표시할 이미지이다</li>
</ul>
<p>waitKey()</p>
<ul>
<li>cv::waitKey(int delay = 0)</li>
<li>키보드 이벤트를 대기하는 함수</li>
<li>인자는 대기 시간을 밀리초 단위로 지정하며, 0은 무한히 대기하  겠다는 의미로 이 함수는 사용자가 키를 누를 때까지 프로그램을 일시 중지시킨다</li>
</ul>
<p>namedWindow()</p>
<ul>
<li>cv::namedWindow(const String&amp; winname, int flags = WINDOW_AUTOSIZE)</li>
<li>이미지를 표시하기 위한 창을 생성하는 함수</li>
</ul>
<p>destroyAllWindows()</p>
<ul>
<li>모든 OpenCV 창을 닫는 함수</li>
</ul>
<pre><code class="language-cpp">
#include &lt;opencv2/opencv.hpp&gt;

int main() {
    // 이미지를 컬러 이미지로 읽습니다. cv::IMREAD_COLOR 부분은 1이 들어가도 되지만 코드의 가독성을 위해 이렇게 사용
    cv::Mat img = cv::imread(&quot;image.jpg&quot;, cv::IMREAD_COLOR);

    if (img.empty()) {
        std::cout &lt;&lt; &quot;Could not open or find the image&quot; &lt;&lt; std::endl;
        return -1;
    }

    // 이미지를 Display window라는 창의 화면에 표시합니다.
    cv::namedWindow(&quot;Display window&quot;, cv::WINDOW_AUTOSIZE);
    cv::imshow(&quot;Display window&quot;, img);

    // 키 입력을 대기합니다.
    cv::waitKey(0);

    // 아무 키 입력이 들어오면 이미지를 output.jpg라는 이름으로 저장합니다.
    cv::imwrite(&quot;output.jpg&quot;, img);

    return 0;
}

</code></pre>
<hr>
<h4 id="도형-그리기-함수">도형 그리기 함수</h4>
<p>cv::line()</p>
<ul>
<li>이미지에 직선을 그림</li>
<li>cv::line(cv::Mat&amp; img, Point pt1, Point pt2, const Scalar&amp; color, int thickness=1, int lineType=8, int shift=0)</li>
<li>img: 이미지, pt1과 pt2: 직선의 시작점과 끝점, color: 선의 색상, thickness: 선의 두께</li>
</ul>
<p>cv::rectangle()</p>
<ul>
<li>이미지에 사각형을 그림</li>
<li>cv::rectangle(cv::Mat&amp; img, Point pt1, Point pt2, const Scalar&amp; color, int thickness=1, int lineType=8, int shift=0)</li>
<li>img: 이미지, pt1과 pt2: 사각형의 왼쪽 위와 오른쪽 아래, color: 선의 색상, thickness: 선의 두께</li>
</ul>
<p>cv::circle()</p>
<ul>
<li>이미지에 원을 그림</li>
<li>cv::circle(cv::Mat&amp; img, Point center, int radius, const Scalar&amp; color, int thickness=1, int lineType=8, int shift=0)</li>
<li>img: 이미지, center: 원의 중심, radius: 원의 반지름, color: 원의 색상, thickness: 원의 두께</li>
</ul>
<p>cv::ellipse()</p>
<ul>
<li>타원 그리는 함수</li>
<li>cv::ellipse(cv::Mat&amp; img, Point center, Size axes, double angle, double startAngle, double endAngle, const Scalar&amp; color, int thickness=1, int lineType=8, int shift=0)</li>
<li>img: 이미지, center: 타원의 중심, axes: 주축의 길이, angle: 타원의 기울기, startAngle와 endAngle: 타원 호의 시작 각도와 끝 각도, color: 타원의 색상, thickness: 타원의 두께</li>
</ul>
<p>cv::polylines()</p>
<ul>
<li>다각형 그려주는 함수</li>
</ul>
<p>cv::putText()</p>
<ul>
<li>이미지에 텍스트를 그려주는 함수</li>
</ul>
<hr>
<p>Mat.type()</p>
<ul>
<li>행렬의 데이터 타입을 반환. 행렬의 깊이와 채널 수를 포함하는 정수로 위에서 봤던 CV_8UC3, CV_32FC1과 같은 형태로 반환된다</li>
</ul>
<p>Mat.depth()</p>
<ul>
<li>행렬의 깊이를 반환한다
<a href="https://docs.opencv.org/2.4/modules/core/doc/basic_structures.html#mat-type">https://docs.opencv.org/2.4/modules/core/doc/basic_structures.html#mat-type</a>
깊이는 공식 문서에서 확인해보자 채널 수는 깊이에 무관하며
8U=0, 8S=1 16S=2, 16U=3, 32U=4, 32F=5로 구분 </li>
</ul>
<p>Mat::zeros()</p>
<ul>
<li>새로운 행렬을 생성할 때 모든 원소 값을 0으로 초기화하는 경우에 사용</li>
</ul>
<p>Mat::ones()</p>
<ul>
<li>모든 원소가 1로 초기화된 행렬을 생성하는 경우에 사용</li>
</ul>
<p>Mat::eye()</p>
<ul>
<li>단위 행렬을 생성할때 사용</li>
</ul>
<p>img.clone()</p>
<ul>
<li>이미지를 복사</li>
</ul>
<p>img.copyTo(Mat M)</p>
<ul>
<li>이미지의 카피본을 M 객체가 가르키도록</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Filter]]></title>
            <link>https://velog.io/@gks970113-woo/Filter</link>
            <guid>https://velog.io/@gks970113-woo/Filter</guid>
            <pubDate>Thu, 04 May 2023 11:40:50 GMT</pubDate>
            <description><![CDATA[<h1 id="filter">Filter</h1>
<p>자율주행 분야에서 필터(filter)는 주로 센서 데이터를 처리하고 차량 상태를 추정하는데 사용된다. 센서 데이터는 종종 잡음이나 오차가 있으며 필터는 이러한 데이터에서 원하는 정보를 추출하고 불확실성을 줄이는데 도움을 준다</p>
<h2 id="재귀-필터recursive-filter">재귀 필터(Recursive filter)</h2>
<ul>
<li>현재 상태를 추정하기 위해 이전 시점의 상태 추정값과 현재 시점의 측정값을 사용</li>
<li>계산의 효율성이 높고 온라인 구현이 가능</li>
<li>차량의 속도, 위치, 방향, 자세 등의 상태를 추정</li>
<li>추정한 추정치는 주변 환경 인식, 경로 계획, 제어 등의 모듈에 사용</li>
</ul>
<h4 id="평균-필터average-filter">평균 필터(Average filter)</h4>
<p>평균필터의 배치식</p>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/220d25fb-9836-46e0-beb0-c34b928c9ecf/image.png" alt=""></p>
<p>평균필터의 재귀식과 유도 과정</p>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/227446c4-74b5-4e54-9a52-d06b5f955525/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/20671d5f-99c3-4000-b796-3f09fa30198f/image.png" alt=""></p>
<ul>
<li>입력 신호의 슬라이딩 윈도우 내에서 샘플들의 산술 평균을 구해 잡음을 제거하고 신호를 부드럽게 만듬</li>
<li>매우 간단하며 실행 속도가 빠르며 계산적으로 효율적이다</li>
<li>시계열 데이터의 단기적인 변동을 줄이고 잡음을 제거하는데 효과적이다</li>
<li>날카로운 변화를 가진 신호의 경우 평균값을 내는 특성을 가진 필터기 때문에 신호의 특징을 손상시킨다</li>
<li>선형 시스템에만 적용되며 비선형 시스템에는 적합하지 않다</li>
<li>대역폭이 좁은 노이즈를 제거하는 데는 덜 효과적이다</li>
</ul>
<h4 id="이동-평균-필터moving-average-filter">이동 평균 필터(Moving average filter)</h4>
<p>이동 평균 필터의 배치식</p>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/7e0c92dc-3642-49a7-b9ee-55596d586fb0/image.png" alt=""></p>
<p>이동 평균 필터의 재귀식과 유도 과정</p>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/b948cae9-5e56-4bf5-bae1-ae1faf80a0ae/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/52f38a60-96a8-403e-b6ea-ce0766c3c0b2/image.png" alt=""></p>
<ul>
<li>평균 필터와 같은 원리로 잡음을 제거하고 신호를 부드럽게 만들지만 새로운 값이 들어오면 오래된 값을 제거한다</li>
<li>기존의 평균 필터와 엄청난 차이를 보이지는 않음</li>
</ul>
<h4 id="저주파-통과-필터low-pass-filter-lpf">저주파 통과 필터(Low pass filter, LPF)</h4>
<p>저주파 통과 필터의 배치식</p>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/89d8ef6f-4504-4c46-a5a2-ffdb2681dd03/image.png" alt=""></p>
<p>저주파 통과 필터의 재귀식</p>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/0d53af38-4eb0-48de-a699-95f9c8618f2f/image.png" alt=""></p>
<ul>
<li>동일한 가중치의 이동평균</li>
<li>최근 데이터의 가중치를 높게 설정한다</li>
<li>센서 데이터와 함께 들어오는 노이즈와 고주파 성분에서 노이즈를 제거해 원하는 정보만을 추출</li>
<li>필터링에 의해 중요한 정보를 손실할 수 있으며 이로 인해 신호 왜곡이 발생해 성능에 영향을 미칠 수 있다</li>
</ul>
<h4 id="칼만-필터kalman-filter">칼만 필터(Kalman filter)</h4>
<ul>
<li>입력과 출력이 하나씩인 간단한 구조로 되어있다</li>
<li>선형 동적 시스템에 대해 최적의 상태를 추정하는 재귀 필터링 알고리즘이다</li>
<li>불확실한 관측 값을 기반으로 시스템의 상태를 추정하고 센서 데이터 융합, 노이즈 제거 및 상태 예측을 할 수 있다</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Coordinate State Space & Modeling ]]></title>
            <link>https://velog.io/@gks970113-woo/%EC%9E%90%EC%9C%A8%EC%A3%BC%ED%96%89%EC%A2%8C%ED%91%9C-%EC%8B%9C%EC%8A%A4%ED%85%9C</link>
            <guid>https://velog.io/@gks970113-woo/%EC%9E%90%EC%9C%A8%EC%A3%BC%ED%96%89%EC%A2%8C%ED%91%9C-%EC%8B%9C%EC%8A%A4%ED%85%9C</guid>
            <pubDate>Thu, 04 May 2023 08:56:36 GMT</pubDate>
            <description><![CDATA[<h1 id="coordinate-state-space">Coordinate State Space</h1>
<p>좌표 상태 공간(Coordinate State Space)은 자율주행 시스템에 사용되는 공간 표현 방식이다
이 공간에서 다양한 요소들이 동작하며, 그 요소들의 상태와 위치를 파악하고 추적하는 데 사용된다</p>
<h2 id="coordinate-system">Coordinate system</h2>
<p>좌표 시스템(Coordinate System)은 좌표 상태 공간에서 요소들의 위치를 정의하는 방식</p>
<h3 id="월드-좌표-시스템world-coordinate-system">월드 좌표 시스템(World Coordinate System)</h3>
<p>월드 좌표(World Coordinate)는 글로벌 좌표보다 넓은 의미로 사용되며, 특정 프레임워크나 시뮬레이션에서 전체 공간을 기준으로 한 좌표계를 의미한다
일반적으로 3D 공간에서 사용되며, 로봇공학, 컴퓨터 그래픽스 및 가상 현실에서 널리 사용된다
월드 좌표계에서 객체의 위치와 방향은 월드 프레임(World Frame)에 상대적으로 정의된다</p>
<h3 id="글로벌-좌표-시스템global-coordinate-system">글로벌 좌표 시스템(Global Coordinate System)</h3>
<ul>
<li>지구 표면에 기반하여 전 세계적인 위치를 나타냄</li>
<li>위도와 경도로 구성되며, GPS 같은 글로벌 위치 지정 시스템에서 사용</li>
<li>자율주행 차량이 글로벌 위치를 파악하는 데 사용된다</li>
<li>ex) 현재 차량의 글로벌 좌표는 약 북위(latitude) 37.5665도 동경(longtitude) 126.9780도로 되어있다</li>
</ul>
<h3 id="지역-좌표-시스템local-coordinate-system">지역 좌표 시스템(Local Coordinate System)</h3>
<ul>
<li>자율주행 차량의 주변 환경에 초점을 맞춰 설계</li>
<li>일반적으로 차량의 위치를 원점으로 하는 평면 좌표계를 사용</li>
<li>차량 주변의 다른 차량, 보행자, 장애물 등의 상대적 위치를 표현</li>
<li>ex) 자율주행 차량 기준으로 3m 앞, 2m 오른쪽에 위치한 보행자는(3,2)로 표시</li>
</ul>
<h3 id="차량-좌표-시스템vehicle-coordinate-system">차량 좌표 시스템(Vehicle Coordinate System)</h3>
<ul>
<li>자율주행 차량의 내부 구성 요소와 연관된 좌표 시스템이다</li>
<li>일반적으로 차량의 중심을 원점으로 하는 3D 좌표계를 사용한다</li>
<li>차량의 구성 요소 및 센서 위치, 방향 등을 정의함</li>
<li>플레밍의 오른손 법칙처럼 엄지는 z축, 검지는 x축, 중지는 y축의 양의 방향을 나타내줌</li>
<li>ex) 차량 중심으로 부터 1m 앞, 0.5m 왼쪽, 0.2m 위에 위치한 카메라 센서는 차량좌표계로(1, 0.5, 0.2)로 표현</li>
</ul>
<hr>
<h1 id="modeling">Modeling</h1>
<p>모델링(Modeling)은 현실 세계의 현상, 개체, 시스템 등을 수학적, 물리적, 컴퓨터 기반의 모델로 표현하는 과정이다. 모델링을 통해 여러 개체와 문제를 단순화하고 분석 및 예측을 수행한다
다양한 모델링 기법들을 사용해 자율주행 시스템의 성능과 안전성을 높이고 기술 발전을 가속화 한다. 각 모델링 기법은 특정 문제에 대한 해결책을 제공하고 이들을 적절하게 조합해 자율주행 전체 시스템의 효율성과 정확도를 향상 시킨다</p>
<h4 id="1-모델링의-목적">1. 모델링의 목적</h4>
<ul>
<li>이해: 복잡한 상황과 장애물들을 간소화해 이해할 수 있도록 도움을 줌</li>
<li>예측: 모델을 사용해 미래 상황에 대한 예측을 수행할 수 있다</li>
<li>설계: 새로운 시스템이나 프로세스를 설계하기 위해 모델을 사용할 수 있음</li>
<li>최적화: 모델을 기반으로 시스템과 프로세스의 성능을 최적화할 수 있다</li>
<li>시뮬레이션: 모델을 사용해 다양한 상황을 시뮬레이션해 시스템의 동작을 테스트할 수 있다</li>
</ul>
<h4 id="2-모델링-기법">2. 모델링 기법</h4>
<ul>
<li><p>수학적 모델링(Mathematical Modeling): 복잡한 현상과 시스템을 수학적 방정식과 개념을 사용해 표현하는 기법이다. 이를 통해 정량적인 분석과 예측을 수행할 수 있다. 차량 동역학, 제어 이론 및 최적화와 같은 자율주행 시스템의 구성 요소를 모델링한다. 차량의 동작과 제어를 분석하고 최적의 경로를 계획해 차량의 성능을 개선시켜주는 역할을 한다</p>
</li>
<li><p>물리적 모델링(Physical Modeling): 물리적 구조와 동작 원리를 기반으로 한 모델을 생성하는 방법이다. 시스템의 물리적 성질을 이해하고 설계할 수 있다</p>
</li>
<li><p>컴퓨터 모델링(Computer Modeling): 컴퓨터 프로그램을 사용해 현상과 시스템을 모사하는 기법으로 시뮬레이션, 최적화, 인공지능의 분야에서 사용된다. 자율주행 차량은 시뮬레이션을 통해 다양한 주행 상황을 모델링하고 테스트한다. 이를 통해 차량의 성능과 안정성을 평가하고 개선할 수 있다. 시뮬레이션 환경에서 가상 센서, 도로 상황, 기상 조건 등을 조절해 차량의 응답을 관찰할 수 있다</p>
</li>
<li><p>통계 모델링(Statistical Modeling): 데이터를 기반으로 모델링 하는 방식으로 데이터의 패턴을 발견하고 데이터와 관련된 불확실성을 추정하며, 예측을 수행하는데 사용된다. 차량의 센서 데이터나 주행 패턴을 분석해 예측 및 추론을 한다. 회귀 분석, 시계열 분석, 베이지안 추론 등이 있으며 자율 주행에선 칼만 필터(Kalman Filter)와 같은 알고리즘을 사용해 센서 데이터의 노이즈를 줄이고 차량의 위치를 추정할 수 있다</p>
</li>
<li><p>기계 학습 모델링(Machine Learning Modeling): 알고리즘과 데이터를 활용하여 모델링하는 기법으로 데이터로부터 자동으로 모델을 학습하며, 예측, 분류, 군집화 등의 다양한 문제에 적용할 수 있다. 인공신경망, 결정 트리, 서포트 벡터 머신 등이 기계 학습 모델링의 예이다. 자율주행 분야에서는 주로 인공신경망(Deep Learning), 결정 트리, 서포트 벡터 머신 등과 같은 기계 학습 알고리즘을 사용해 센서 데이터로부터 차량의 제어 및 주변 환경 인식 모델을 생성한다. 차량의 경로 계획, 장애물 인식 및 추적, 표지판 및 신호 인식 등의 작업을 수행할 수 있다.</p>
</li>
<li><p>에이전트 기반 모델링(Agent-Based Modeling): 독립적인 에이전트(개체)들이 상호작용하며 전체 시스템의 동작을 구성하는 모델링 기법이다. 자율주행 시스템에서는 도로 상황을 모델링하기 위해 에이전트 기반 모델링을 사용한다. 이 기법은 다른 차량, 보행자, 자전거 등의 독립적인 에이전트와의 상호작용을 통해 전체 시스템의 동작을 이해하고 예측한다</p>
</li>
</ul>
<h4 id="3-수학적-모델링에서-속도와-위치-계산법">3. 수학적 모델링에서 속도와 위치 계산법</h4>
<p>고딩 때 물리를 따로 안한 화1 생1 유저로써 수업을 듣는데 조금 난해해서 따로 공부해가지고 정리해본다.</p>
<p>선형 시스템에서의 계산</p>
<p>F = m*a
힘(F) = 질량(m) * 가속도(a)</p>
<p>자동차에 엑셀을 밟아 전진력이 작용되면 가속도를 계산할 수 있다
a = F/m
가속도(a) = 힘(F)/질량(m)
자동차의 가속도 = 자동차가 나아가는 힘/자동차의 질량</p>
<p>속도(v)와 위치(x) 계산</p>
<p>v = v0 + a<em>t
속도(v) = 자동차의 초기 속도(v0) + 가속도(a)</em>시간(t)</p>
<p>x = x0 + v0<em>t + 0.5</em>a*t^2</p>
<hr>
<h1 id="상태-공간-방정식state-space-equation">상태-공간 방정식(state-space equation)</h1>
<p>동적 시스템을 수학적으로 표현하는 방법이다. 시스템의 상태 변수와 입력 변수 간의 관계를 나타낸 1차 방정식으로 상태 변수는 시스템의 현재 상태를 나타내는 변수, 입력 변수는 외부에서 주어지는 조건이나 값들이다 이 방정식은 선형 및 비선형 시스템 모두에 적용될 수 있다</p>
<h4 id="1-상태-방정식state-equation">1. 상태 방정식(state equation)</h4>
<ul>
<li>상태 방정식은 시스템의 상태 변수들의 변화를 나타낸다</li>
<li>x&#39;(t) = A * x(t) + B * u(t) 와 같은 형태를 가진다</li>
<li>x&#39;(t)는 상태 변수들의 시간에 대한 미분, x(t)는 상태 변수들의 벡터, u(t)는 입력 변수들의 벡터, A는 상태 변환 행렬, B는 입력 행렬이다</li>
</ul>
<h4 id="2-출력-방정식-output-equation">2. 출력 방정식 (output equation)</h4>
<ul>
<li>출력 방정식은 시스템의 출력 변수와 상태 변수, 입력 변수 간의 관계를 나타낸다</li>
<li>y(t) = C * x(t) + D * u(t) 와 같은 형태를 가진다</li>
<li>y(t)는 출력 변수들의 벡터, C는 출력 행렬, D는 직접 전달 행렬이다</li>
</ul>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/383a90b7-bb43-47c2-b945-1c9d3effcd1e/image.png" alt=""></p>
<p>왼쪽은 비선형(Nonlinear) 시스템, 오른쪽은 선형(Linear) 시스템의 상태 공간 방정식이다</p>
<h4 id="1-비선형nonlinear-시스템">1. 비선형(Nonlinear) 시스템</h4>
<p>상태 변수나 입력 변수에 대한 응답이 선형적이지 않은 시스템으로 즉, 상태 변수와 입력 변수 사이의 관계가 비선형 함수로 표현되는 경우를 말한다
예시로 자동차가 있을 때, 차량의 위치와 방향을 상태 변수로 가지고 차량의 속도와 조향 각도를 입력 변수로 가진다</p>
<p>장점</p>
<ul>
<li>정확성: 비선형 시스템의 상태-공간 방정식은 여러 상황을 정확하게 인식하고 반영한다</li>
<li>범용성: 비선형 시스템은 선형 시스템을 포함하는 형태로 비선형 시스템의 이론과 기법또한 선형 시스템에 적용된다</li>
<li>다양성: 선형 시스템에서 나타나지 않는 동적 현상을 포착할 수 있다. 예를 들어 한계 주기 현상, 혼돈, 복잡한 안정성 등이 있다</li>
</ul>
<p>단점</p>
<ul>
<li>복잡성: 비선형 시스템의 상태-공간 방정식은 분석하고 해결하기 어렵다. 선형 시스템에 비해 해석하고 해결할 수 있는 방법이 적거나 없을 가능성이 농후</li>
<li>계산 비용: 비선형 시스템의 제어 및 최적화 문제를 해결하기 위해 수치적 방법을 사용해야 하는데 이 방법은 계산 비용이 높고 실행 시간이 길어진다</li>
<li>제어 설계의 어려움: 선형 시스템에 비해 제어 설계가 어려워 복잡한 기법과 알고리즘이 사용된다</li>
</ul>
<p>예시</p>
<p>상태 변수 x(t)</p>
<ul>
<li>x1(t): 차량의 x-좌표</li>
<li>x2(t): 차량의 y-좌표</li>
<li>x3(t): 차량의 방향(ψ)</li>
</ul>
<p>입력 변수 u(t)</p>
<ul>
<li>u1(t) : 차량의 속도 (v)</li>
<li>u2(t) : 차량의 조향 각도 (δ)</li>
</ul>
<p>상태 방정식의 구성(상태 변수들의 시간에 대한 미분)</p>
<ul>
<li>x1&#39;(t) = v * cos(ψ + δ)</li>
<li>x2&#39;(t) = v * sin(ψ + δ)</li>
<li>x3&#39;(t) = v * sin(δ) / L</li>
<li>L은 차량의 wheelbase(앞바퀴 축과 뒷바퀴 축의 중심부터 중심까지의 거리)</li>
</ul>
<p>상태 방정식의 상태-공간 표현
x&#39;(t) = f(x(t), u(t)) = [v * cos(ψ + δ), v * sin(ψ + δ), v * sin(δ) / L]</p>
<p>출력 방정식은 출력 변수를 설정해야 하는데 설정하지 않았기에 방정식 표현은 생략
차량의 위치(x,y), 차량의 방향(w), 차량의 속도(v), 차간 거리, 차선 인식 및 추적 등이 변수로 설정될 수 있다</p>
<h4 id="2-선형linear-시스템">2. 선형(Linear) 시스템</h4>
<p>시스템의 입출력 사이의 관계가 선형적인 시스템이다. 즉, 상태 변수와 입력 변수 간의 관계가 선형 함수로 표현되는 경우를 말한다</p>
<p>장점</p>
<ul>
<li>분석의 용이성: 선형 시스템은 분석하기 쉽고 다양한 수학적 도구를 사용할 수 있다 따라서 여러 제어 및 추정 알고리즘을 개발할 수 있다</li>
<li>제어 설계의 용이성: 선형 제어 기법을 사용해 차량 동역학을 제어할 수 있다. 간단한 제어 알고리즘을 개발하는데 도움이 됨</li>
</ul>
<p>단점</p>
<ul>
<li>정확성 제한: 실제 차량 동역학의 환경은 비선형적일 수 있다. 따라서 선형 시스템은 완전하게 구현하지 못해 실제 성능과 차이가 발생할 수 있다</li>
<li>범용성 제한: 선형 시스템은 차량 동역학의 복잡한 특성을 잡아내기 어려울 수 있다. 이로 인해 선형 모델의 적용 범위가 제한적일 수 있음</li>
</ul>
<p>예시</p>
<p>상태 변수:</p>
<ul>
<li>x1(t) : 차량의 위치</li>
<li>x2(t) : 차량의 속도</li>
</ul>
<p>입력 변수:</p>
<ul>
<li>u(t) : 가속도</li>
</ul>
<p>선형 상태-공간 방정식 구성(상태 변수들의 시간에 대한 미분)</p>
<p>x&#39;(t) = A * x(t) + B * u(t)</p>
<p>A = [[0, 1], [0, 0]]</p>
<p>B = [[0], [1]]</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[ROS_6) XYcar(자이카) 개념]]></title>
            <link>https://velog.io/@gks970113-woo/ROS6-XYcar%EC%9E%90%EC%9D%B4%EC%B9%B4-%EA%B0%9C%EB%85%90</link>
            <guid>https://velog.io/@gks970113-woo/ROS6-XYcar%EC%9E%90%EC%9D%B4%EC%B9%B4-%EA%B0%9C%EB%85%90</guid>
            <pubDate>Wed, 26 Apr 2023 16:31:28 GMT</pubDate>
            <description><![CDATA[<h1 id="xycar">XYcar</h1>
<p>자이카는 국내 회사 자이트론에서 제작한 자율주행 모형차이다
Xycar-D, Xycar-X, Xycar-C 모델이 있음</p>
<hr>
<h3 id="자이카-소프트웨어-구성">자이카 소프트웨어 구성</h3>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/623e61f8-00ad-49bf-910c-9dad08f8fd57/image.png" alt=""></p>
<h4 id="운영체제">운영체제</h4>
<ul>
<li>리눅스가 설치되어있다(16.04 or 18.04 버전)</li>
</ul>
<h4 id="미들웨어">미들웨어</h4>
<ul>
<li>ROS로 구성되어있다. 각종 센서와 모터제어를 한다</li>
</ul>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/0554b94d-a45d-42ce-99b5-7646c8001191/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/166b06a4-35d8-4ce9-b83d-b8b15513ccb0/image.png" alt=""></p>
<p>장치별 제어를 위해 위와 같은 ROS Package가 구축되어 있음</p>
<h4 id="라이브러리">라이브러리</h4>
<ul>
<li>오픈소스 라이브러리를 활용해 파이썬으로 코딩할 수 있으며 머신 러닝과 영상처리를 도와주는 PyTorch, TensorFl</li>
</ul>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/420c4ea0-aa43-43c6-8845-5a23003de65c/image.png" alt=""></p>
<hr>
<h3 id="자이카-하드웨어-구성">자이카 하드웨어 구성</h3>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/f5e51fcf-cca0-40c0-a0e0-a4ca96e336ab/image.png" alt=""></p>
<h4 id="1-자동차-구동부">1. 자동차 구동부</h4>
<ul>
<li>전후진 + 조향(핸들)</li>
</ul>
<h4 id="2-구동모터">2. 구동모터</h4>
<ul>
<li>모터의 회선 속도는 공급되는 전력의 양에 따라 결정<ul>
<li>배터리 전력이 모터 제어기를 거쳐 모터로 전달</li>
<li>모터의 회전력이 기어 박스를 통해 바퀴의 회전력으로 변환
<img src="https://velog.velcdn.com/images/gks970113-woo/post/38e12224-75c8-4fec-b364-b4f9da931159/image.png" alt=""></li>
</ul>
</li>
</ul>
<h4 id="3-조향모터">3. 조향모터</h4>
<ul>
<li><p>핸들 조작을 위한 모터</p>
<ul>
<li>좌우 정해진 각도 내에서 왔다갔다 왕복 동작</li>
<li>서보 모터 사용</li>
</ul>
</li>
<li><p>PWM(Pulse Width Modulation) 신호로 모터의 회전각도를 조종</p>
<ul>
<li>5V 출력을 on 혹은 off 상태로 유지하는 것이 아닌 빠르게 on/off  상태를 반복</li>
</ul>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/3dae7264-1a51-49da-a6f9-72a4652cc338/image.png" alt=""></p>
</li>
</ul>
<h4 id="4-모터제어기">4. 모터제어기</h4>
<ul>
<li><p>ESC(Electronic Speed Controller)</p>
<ul>
<li>모터 스피드 제어기</li>
</ul>
</li>
<li><p>VESC(Vedder ESC)</p>
<ul>
<li>ESC 오픈소스 프로젝트 결과물로 성능을 향상</li>
<li>구동 모터의 전후진 속도 제어</li>
<li>조향모터의 좌우 회전 제어</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/0160ee8e-c8e5-4480-ae45-80b01450e400/image.png" alt=""></p>
<h4 id="5-esc-모터-제어기">5. ESC 모터 제어기</h4>
<ul>
<li>ESC -&gt; 무선조종기를 사용해 제어(RC카 조종)<ul>
<li>차량의 조행속도를 조절</li>
<li>차량의 주행방향을 조절</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[OpenCV_1) OpenCV와 Mat클래스]]></title>
            <link>https://velog.io/@gks970113-woo/OpenCV1-OpenCV%EC%99%80-Mat%ED%81%B4%EB%9E%98%EC%8A%A4</link>
            <guid>https://velog.io/@gks970113-woo/OpenCV1-OpenCV%EC%99%80-Mat%ED%81%B4%EB%9E%98%EC%8A%A4</guid>
            <pubDate>Wed, 26 Apr 2023 05:14:18 GMT</pubDate>
            <description><![CDATA[<h1 id="opencv">OpenCV</h1>
<ul>
<li>영상 처리와 컴퓨터 비전을 위한 오픈 소스 라이브러리(BSD 라이선스)</li>
<li>C, C++, Python, Java 등 여러 언어에서 사용 가능</li>
<li>대부분의 운영체제 지원(Linux, Windows, Mac OS, Android)</li>
<li>이미지와 비디오 처리, 객체 추적, 얼굴 인식, 모션 감지 등의 다양한 기능을 제공</li>
<li>자율 주행 분야에서도 카메라를 이용한 차선 인식, 신호 인식, 장애물 탐지 등에 사용</li>
<li>머신러닝 모델과 연동해 이미지 분류, 객체 인식, 얼굴 인식 등의 작업 수행</li>
</ul>
<h3 id="opencv-버전">OpenCV 버전</h3>
<p>1.x</p>
<ul>
<li>OpenCV의 초기 버전으로, 2000년대 초반에 개발</li>
<li>C 라이브러리로 구현되어 있으며, 기본적인 영상 처리 기능을 제공</li>
</ul>
<p>2.x</p>
<ul>
<li>2010년대 초반에 출시</li>
<li>C++로 구현, 다양한 기능 추가 Python, Java 등의 언어도 지원</li>
</ul>
<p>3.x</p>
<ul>
<li>2010년대 후반에 출시</li>
<li>OpenCL, CUDA 등의 기술을 활용하여 GPU 가속화를 지원</li>
<li>특징점 추출 알고리즘과 관련 기능이 보강 및 추가 됨</li>
</ul>
<p>4.x</p>
<ul>
<li>2019년에 출시된 최신 버전</li>
<li>C++11 및 C++14 표준을 지원</li>
<li>이전 버전에 비해 빠른 속도와 개선된 딥러닝 모듈, 향상된 성능, Python과의 연동성 등이 강화</li>
<li>딥러닝 모델과의 통합이 가능(Yolo 등)</li>
</ul>
<hr>
<h3 id="기본-자료구조-및-픽셀-접근">기본 자료구조 및 픽셀 접근</h3>
<h4 id="mat">MAT</h4>
<ul>
<li>영상 및 이미지 데이터를 저장하는 행렬(Matrix) 클래스</li>
<li>여러 차원의 배열로 이루어져 있으며 한 픽셀 당 여러 채널(RGB, BGR, Grayscale 등)의 정보를 가지고 있음</li>
<li>C++로 구현되어 있으며 이미지 및 비디오 데이터를 처리할 때 매우 편리하게 사용 가능</li>
<li>행렬 연산, 원하는 채널의 추출 및 변경, ROI(Region of Interest = 관심영역)의 추출 등 다양한 기능을 제공</li>
<li>메모리 자동으로 할당하며 생성 시 크기, 데이터 타입, 초기화 값 등을 설정할 수 있다</li>
<li>이미지 파일에서 데이터를 읽어와 Mat 형태로 편환하거나 Mat 형태의 데이터를 이미지 파일로 저장할 수 있음</li>
<li>영상을 흑백 이미지로 변환하거나 이미지에서 특정 색상의 물체를 검출하는 작업에서 사용</li>
</ul>
<h4 id="픽셀-타입">픽셀 타입</h4>
<ul>
<li>BGR(default)</li>
<li>GRAYSCALE</li>
<li>HSV</li>
<li>YUV ..</li>
</ul>
<hr>
<h3 id="데이터-선언-방법">데이터 선언 방법</h3>
<pre><code class="language-cpp">Mat M;
Mat M(rows, colums, pixel_type);
Mat M(rows, colums, pixel_type, initial_value);
Mat M(Size(width, height), pixel_type, initial_value);</code></pre>
<h4 id="예시">예시</h4>
<pre><code class="language-cpp">Mat data(1, 3, CV_32FC1);</code></pre>
<p>3개의 요소를 가진 1차원 행렬 데이터 타입은 32비트 실수형(Float)</p>
<pre><code class="language-cpp">Mat img(240, 320, CV_8UC1);</code></pre>
<p>320x240 크기의 흑백 이미지를 저장하기 위한 1채널 Grayscale 데이터 타입의 Mat 객체를 생성</p>
<pre><code class="language-cpp">Mat img(240, 320, CV_8UC3); </code></pre>
<p>320x240 크기의 컬러 이미지를 저장하기 위한 3채널 BGR 데이터 타입의 Mat 객체를 생성</p>
<pre><code class="language-cpp">Mat video(240, 320, CV_8UC3, Scalar(0, 0, 0));</code></pre>
<p>320x240 크기의 3채널(BGR) 동영상을 저장하기 위한 Mat 객체를 생성
Scalar(0, 0, 0)은 초기화 값으로 검은색을 지정, video.at<Vec3b>(i, j)[0]은 i번째 프레임에서 j행 j열의 Blue 채널 픽셀 값</p>
<p>  <img src="https://velog.velcdn.com/images/gks970113-woo/post/0d9e3a2e-580f-4c90-97cb-962d654508f6/image.png" alt=""></p>
<p>  위 이미지 처럼 Mat 데이터를 선언하고 초기화해서 값을 지정해줄 수 있다. 픽셀의 사이즈를 설정해주고 컬러의 데이터 타입을 지정하며 1채널이면 1개의 Scale 값을 3채널이면 3종류의 Scale 값을 설정해서 원하는 크기 원하는 색상을 설정할 수 있다</p>
<hr>
<h3 id="함수-정리">함수 정리</h3>
<p>생성자 함수</p>
<ul>
<li>Mat() : 빈 Mat 객체를 생성  </li>
<li>Mat(int rows, int cols, int type): rows x cols 크기의 type 데이터 타입 행렬을 생성</li>
<li>Mat(Size size, int type): size 크기의 type 데이터 타입 행렬을 생성</li>
<li>Mat(int ndims, const int* sizes, int type): ndims 차원을 가진 sizes 배열 크기의 type 데이터 타입 행렬을 생성</li>
</ul>
<p>초기화 함수</p>
<ul>
<li>zeros(Size size, int type): 모든 요소를 0으로 초기화하는 size 크기의 type 데이터 타입 행렬을 생성</li>
<li>ones(Size size, int type): 모든 요소를 1로 초기화하는 size 크기의 type 데이터 타입 행렬을 생성</li>
<li>eye(int rows, int cols, int type): 대각 요소를 1로 초기화하고 나머지 요소를 0으로 초기화하는 rows x cols 크기의 type 데이터 타입 행렬을 생성</li>
</ul>
<p>그리기 함수</p>
<ul>
<li><p>rectangle(Mat&amp; img, Point pt1, Point pt2, const Scalar&amp; color, int thickness, int lineType, int shift=0): pt1, pt2 좌표를 꼭짓점으로 하는 사각형을 img Mat 객체에 그림</p>
<ul>
<li>thickness : 선의 두께</li>
<li>color : 사각형 색상</li>
<li>lineType : 선의 타입(LINE_4, LINE_8, LINE_AA 등)</li>
<li>shift : 좌표 비트 시프트<pre><code class="language-cpp">img = cv2.rectangle(img, (100, 100), (300, 500), (0, 255, 0), 3) </code></pre>
</li>
</ul>
</li>
<li><p>circle(Mat&amp; img, Point center, int radius, const Scalar&amp; color, int thickness, int lineType, int shift=0): center 좌표를 중심으로 하고 radius 크기의 원을 img Mat 객체에 그림</p>
</li>
</ul>
<pre><code class="language-cpp">img = cv2.circle(img, (300, 400), 100, (0, 0, 255), 2) </code></pre>
<ul>
<li>line(Mat&amp; img, Point pt1, Point pt2, const Scalar&amp; color, int thickness, int lineType, int shift=0): pt1에서 pt2까지의 직선을 img Mat 객체에 그림</li>
</ul>
<pre><code class="language-cpp">img = cv2.line(img, (511, 511), (255, 0, 0), 5) </code></pre>
<ul>
<li>putText(Mat&amp; img, const String&amp; text, Point org, int fontFace, double fontScale, const Scalar&amp; color, int thickness, int lineType, bool bottomLeftOrigin=false): org 좌표에서 시작하여 text 문자열을 img Mat 객체에 출력<ul>
<li>fontFace : 글꼴 타입</li>
<li>bottomLeftOrigin : true로 하면 org 좌표를 문자열 왼쪽 아래로 지정</li>
</ul>
</li>
</ul>
<pre><code class="language-cpp">img = cv2.putText(img, &#39;Test,(10, 50), cv2.FONT_HERSHEY_SIMPLEX, 4, (255, 255, 255))</code></pre>
<p>기타 함수</p>
<ul>
<li>at(): 지정된 위치의 요소에 대한 참조를 반환</li>
<li>size(): 행렬의 크기를 반환</li>
<li>resize(InputArray src, OutputArray dst, Size dsize, double fx=0, double fy=0, int interpolation=INTER_LINEAR); : 원본 이미지를 새로운 크기로 변환하여 반환, 변환된 이미지는 새로운 Mat 객체에 저장</li>
<li>type(): 행렬의 데이터 타입을 반환</li>
<li>channels(): 행렬의 채널 수를 반환</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[ROS_5) 노드 간 N:N 통신 주고받기 & 나만의 메시지 만들기]]></title>
            <link>https://velog.io/@gks970113-woo/ROS5-%EB%85%B8%EB%93%9C-%EA%B0%84-NN-%ED%86%B5%EC%8B%A0-%EC%A3%BC%EA%B3%A0%EB%B0%9B%EA%B8%B0</link>
            <guid>https://velog.io/@gks970113-woo/ROS5-%EB%85%B8%EB%93%9C-%EA%B0%84-NN-%ED%86%B5%EC%8B%A0-%EC%A3%BC%EA%B3%A0%EB%B0%9B%EA%B8%B0</guid>
            <pubDate>Tue, 25 Apr 2023 15:49:59 GMT</pubDate>
            <description><![CDATA[<h2 id="11-통신-예제">1:1 통신 예제</h2>
<h4 id="통신-구조">통신 구조</h4>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/a03ac5be-0ebe-4fe9-a83b-b0736103ca62/image.png" alt=""></p>
<hr>
<h4 id="directory-구조">Directory 구조</h4>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/fd66b121-87a7-4c60-8719-0c4c67accb92/image.png" alt=""></p>
<hr>
<pre><code>$ cd ~/xycar_ws/src
$ catkin_create_pkg msg_send std_msgs rospy
//패키지 만든다, 패키지 이름, 패키지가 의존하고 있는 다른 패키지 나열
$ mkdir launch
//msg_send 아래 launch 파일을 만듬(xml로 이루어짐)
$ cm
//새로 만든 패키지를 빌드</code></pre><h4 id="teacherpy">teacher.py</h4>
<pre><code class="language-python">#!/usr/bin/env python

```
파이썬에서는 #!으로 시작하는 라인을 Shebang 라인이라고 한다. Sharp(#) + Bang(!)의 합성어로 스크립트 파일의 첫줄에 사용되고 스크립트를 실행하는 데 사용되는 인터프리터를 지정한다. shebang이 들어가면 터미널에서 python을 붙이지 않고 바로 ./teacher.py 형태로 실행도 가능하다
```
import rospy
from std_msgs.msg import String

```
rospy 라이브러리를 import한다. rospy는 ROS에서 파이썬을 사용하기 위한 라이브러리이다.
std_msgs.msg 라는 ROS의 표준 패키지에서 String 부분을 가져와 사용하겠다는 의미이다. 더 여러개의 모듈을 가져올 수 있다

```

rospy.init_node(&#39;teacher&#39;)

#정수나 문자열을 선언하고 초기화하는 것 처럼 teacher라는 이름의 ROS노드를 선언하고 초기화

pub = rospy.Publisher(&#39;my_topic&#39;, String)

#my_topic 이라는 토픽에 string 메시지를 받아 발행하기 위해 Publisher 객체를 선언했다
#2번째 매개변수 String은 위에서 선언한 std_msgs.msg import String의 String이다

rate = rospy.Rate(2)

#발행 빈도를 2Hz로 설정하는 부분이다. 1초에 2번 반복할 수 있도록 rate 객체를 선언했다

while not rospy.is_shutdown(): #rospy가 종료되기 전까지 무한히 반복하면서
    pub.publish(&#39;call me please&#39;)
    rate.sleep()

#위에서 발행한 pub을 이용해 my_topic에 call me please 라는 문자열 메시지를 계속 발행한다
#위에서 호출한 rate 객체에 sleep()함수를 걸어줬다. 이는 while문이 종료되기 전까지 무한 반복되는 동안
#while 반복문 안에 rate.sleep()이 있기 때문에 0.5초에 한번씩 동작할 수 있도록 제어해주는 역할을 한다. </code></pre>
<h4 id="studentpy">student.py</h4>
<pre><code class="language-python">#!/usr/bin/env python

import rospy
from std_msgs.msg import String

```
teacher.py에서 설명한 바와 같이 첫번째 줄은 스크립트가 파이썬 인터프리터를 사용해 실행할 수 있도록 하는
shebang라인이다. python을 붙이지 않고 ./student.py 와 같은 명령만으로도 실행시킬 수 있다
ROS 노드를 파이썬 코드로 생성하고 통신할 수 있도록 하는 라이브러리를 import하고
ROS 표준 메시지 패키지 std_mgms에서 문자열 타입인 String 메시지 타입을 가져오도록 하는 라인이다
```

def callback(msg):
    print msg.data

# def는 함수를 선언하고 정의할때 쓰는 용어다. callback이라는 함수를(msg)라는 매개변수를 가지고 있는 채로 선언했다
#이 함수는 callback(msg)형태로 사용하는데 msg에 들어온 값을 print(출력) 한다

rospy.init_node(&#39;student&#39;)

#teacher.py와 같이 student라는 이름의 ROS 노드를 선언하고 초기화 해준다. 다른 노드와 통신하기 위함이다

sub = rospy.Subscriber(&#39;my_topic&#39;, String, callback)

#my_topic에 대해서 구독자를 생성하고 String 타입의 메시지를 받아 callback 함수를 호출한다
#그리고 구독자의 인스턴스는 sub에 저장이 되며 토픽(메시지)를 받을 때 마다 callback함수가 호출된다

rospy.spin()

#rospy.spin()함수는 노드가 종료될 때까지 메시지를 계속 받고 callback 함수를 호출하는 무한 루프를 생성한다
#rospy.sleep()과 유사할 수 있는데 이 함수는 spin()과 다르게 특정한 시간동안만 동작한다는 부분이다</code></pre>
<h4 id="launch-파일-작성-및-실행">Launch 파일 작성 및 실행</h4>
<pre><code class="language-bash">$ gedit m_send.launch
$ cm
//빌드
$ chmod +x teacher.py student.py
$ roslaunch msg_send m_send.launch</code></pre>
<pre><code class="language-html">&lt;launch&gt;
    &lt;node pkg=&quot;msg_send&quot; type=&quot;teacher.py&quot; name=&quot;Teacher&quot;/&gt;
    &lt;node pks=&quot;msg_send&quot; type=&quot;student.py&quot; name=&quot;student&quot; output=&quot;screen&quot;/&gt;
&lt;/launch&gt;</code></pre>
<hr>
<h2 id="nn-통신-예제">N:N 통신 예제</h2>
<h4 id="통신-구조-1">통신 구조</h4>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/fb8e5aed-76e5-41d5-96fd-df0f6816d457/image.png" alt=""></p>
<p>코드는 위의 코드와 똑같이 해주면 되는데 하나의 코드로 여러 개의 노드를 연결하기 위해선 각 노드의 이름이 달라야 한다 따라서</p>
<ul>
<li>노드의 init 함수에서  anonymous=True ㄱ밧을 넣어주면 노드 이름을 자동 설정할 수 있다</li>
<li>ex) rospy.init_node(&#39;student&#39;, anonymous=True)</li>
</ul>
<p>터미널을 띄워 놓고</p>
<pre><code class="language-bash">$ rosrun msg_send teacher_int-1.py
$ rosrun msg_send teacher_int-2.py
$ rosrun msg_send teacher_int-3.py</code></pre>
<p>처럼 3개의 파일을 적어놓고 3번 실행하는 것이 아니라 </p>
<p>launch 파일을 사용해서 roslaunch 명령으로 여러 노드를 띄울 수 있다</p>
<pre><code>&lt;launch&gt;
    &lt;node pkg=&quot;msg_send&quot; type=&quot;teacher_int.py&quot; name=&quot;teacher1&quot;/&gt;
    &lt;node pkg=&quot;msg_send&quot; type=&quot;teacher_int.py&quot; name=&quot;teacher&quot;2/&gt;
    &lt;node pkg=&quot;msg_send&quot; type=&quot;teacher_int.py&quot; name=&quot;teacher3&quot;/&gt;
    &lt;node pks=&quot;msg_send&quot; type=&quot;student_int.py&quot; name=&quot;student1&quot; output=&quot;screen&quot;/&gt;
    &lt;node pks=&quot;msg_send&quot; type=&quot;student_int.py&quot; name=&quot;student2&quot; output=&quot;screen&quot;/&gt;
    &lt;node pks=&quot;msg_send&quot; type=&quot;student_int.py&quot; name=&quot;student3&quot; output=&quot;screen&quot;/&gt;
&lt;/launch&gt;</code></pre><hr>
<h2 id="1n-통신-n1-통신">1:N 통신, N:1 통신</h2>
<pre><code>&lt;launch&gt;
    &lt;node pkg=&quot;msg_send&quot; type=&quot;teacher_int.py&quot; name=&quot;teacher&quot;/&gt;
    &lt;node pks=&quot;msg_send&quot; type=&quot;student_int.py&quot; name=&quot;student1&quot; output=&quot;screen&quot;/&gt;
    &lt;node pks=&quot;msg_send&quot; type=&quot;student_int.py&quot; name=&quot;student2&quot; output=&quot;screen&quot;/&gt;
    &lt;node pks=&quot;msg_send&quot; type=&quot;student_int.py&quot; name=&quot;student3&quot; output=&quot;screen&quot;/&gt;
&lt;/launch&gt;</code></pre></br>

<pre><code>&lt;launch&gt;
    &lt;node pkg=&quot;msg_send&quot; type=&quot;teacher_int.py&quot; name=&quot;teacher1&quot;/&gt;
    &lt;node pkg=&quot;msg_send&quot; type=&quot;teacher_int.py&quot; name=&quot;teacher&quot;2/&gt;
    &lt;node pkg=&quot;msg_send&quot; type=&quot;teacher_int.py&quot; name=&quot;teacher3&quot;/&gt;
    &lt;node pks=&quot;msg_send&quot; type=&quot;student_int.py&quot; name=&quot;student&quot; output=&quot;screen&quot;/&gt;
&lt;/launch&gt;</code></pre><p>응용해서 1:N 이나 N:1이나 코드에는 anonymous=True 값을 설정해줘서 여러개의 노드를 띄워도 알아서 이름을 바꿔 생성할 수 있도록 처리해준뒤 Launch 파일의 xml 코드를 수정해서 한번에 여러개의 노드를 실행시킬 수 있다</p>
<hr>
<h2 id="나만의-메시지-만들기">나만의 메시지 만들기</h2>
<h4 id="폴더-구조">폴더 구조</h4>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/5241933d-c30c-4f42-96e4-b5c496bd99b2/image.png" alt=""></p>
<h4 id="코드">코드</h4>
<pre><code class="language-bash">$ cd ~/xycar_ws/src
$ roscd msg_send
$ mkdir msg
$ cd msg
$ gedit my_msg.msg</code></pre>
<h4 id="my_msgmsg">my_msg.msg</h4>
<pre><code>string first_name
string last_name
int32 age
int32 score
string phone_number
int32 id_number</code></pre><h4 id="msg_senderpy">msg_sender.py</h4>
<pre><code class="language-py">#!/usr/bin/env python

import rospy
from msg_send.msg import my_msg

rospy.init_node(&#39;msg_sender&#39;, anonymous=True)
pub = rospy.Publisher(&#39;msg_to_xycar&#39;, my_msg)

msg = my_msg()
msg.first_name = &quot;woojin&quot;
msg.last_name = &quot;Han&quot;
msg.id_number = 12345678
msg.phone_number = &quot;010-1234-5678&quot;

rate = rospy.Rate(1)
while not rospy.is_shutdown():
    pub.publish(msg)
    print(&quot;sending message&quot;)
    rate.sleep()</code></pre>
<h4 id="msg_receiverpy">msg_receiver.py</h4>
<pre><code class="language-py">#!/usr/bin/env python3

import rospy
from msg_send.msg import my_msg

def callback(msg):
    print (&quot;1. Name: &quot;, msg.last_name + msg.first_name)
    print (&quot;2. ID: &quot;, msg.id_number)
    print (&quot;3. Phone Number: &quot; , msg.phone_number)

rospy.init_node(&#39;msg_receiver&#39;, anonymous=True)

sub = rospy.Subscriber(&#39;msg_to_xycar&#39;, my_msg, callback)

rospy.spin()</code></pre>
<h4 id="packagexml-cmakeliststxt-수정">package.xml, CmakeLists.txt 수정</h4>
<ul>
<li>~/xycar_ws/src/msg_send/에 위치해있음<pre><code class="language-bash">$ gedit package.xml</code></pre>
파일 아래 쪽에</li>
<li><build_depend>message_generation</build_depend></li>
<li><exec_depend>message_runtime</exec_depend></li>
</ul>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/5aefee9c-22fb-4099-838a-e594b5a38cae/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/a942420c-d133-4ad8-b2d5-891dd9204ca6/image.png" alt=""></p>
<pre><code class="language-bash">$ cm
$ rosmsg show my_msg
//결과 확인
$ ~/xycar_ws/devel/lib/python2.7/dist_packages/msg_send/msg
//여기 디렉토리에서 생성된 msg 확인 가능</code></pre>
<pre><code>$ cm
$ roscore
$ rosrun msg_send msg_receiver.py
$ rosrun msg_send msg.sender.py</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[ROS_4) ROS 기본 예제]]></title>
            <link>https://velog.io/@gks970113-woo/ROS4-ROS-%EA%B8%B0%EB%B3%B8-%EC%98%88%EC%A0%9C</link>
            <guid>https://velog.io/@gks970113-woo/ROS4-ROS-%EA%B8%B0%EB%B3%B8-%EC%98%88%EC%A0%9C</guid>
            <pubDate>Sat, 22 Apr 2023 17:32:52 GMT</pubDate>
            <description><![CDATA[<h2 id="pubpy-생성">pub.py 생성</h2>
<pre><code>#! /usr/bin/env python

import rospy
from geometry_msgs.msg import Twist

rospy.init_node(&#39;my_node&#39;, anonymous=True)
// my_node 노드를 생성한다
pub = rospy.Publisher(&#39; /turtle1/cmd_vel&#39;, Twist, queue_size=10)
//발행자인 Publisher 객체를 생성

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

rate = rospy.Rate(1)
//1HZ = 1초에 1번씩 반복

while not rospy.is_shutdown():
    pub.publish(msg)
    rate.sleep()
//종료될때까지 게속 1초 주기로 실행</code></pre><ul>
<li>~/xycar_ws/src/my_pkg1/src 위치에 pub.py라는 이름으로 생성해야함</li>
<li>생성 후 파이썬 코드를 실행시키기 위해 실행권한을 부여해줘야한다</li>
</ul>
<pre><code>$ chmdd +x pub.py
//r : read w : write x : execute
$ ls -l
//실행 권한 부여됐는지 확인</code></pre><h2 id="각-터미널에서-코드-실행">각 터미널에서 코드 실행</h2>
<p>터미널 1</p>
<ul>
<li>roscore 실행<pre><code>$ roscore</code></pre></li>
</ul>
<p>터미널 2</p>
<ul>
<li>turtlesim 노드 실행<pre><code>$ rosrun turtlesim turtlesim_node</code></pre></li>
</ul>
<p>터미널 3</p>
<ul>
<li>pub.py 실행<pre><code>$ chmod +x pub.py
$ rosrun my_pkg1 pub.py</code></pre></li>
</ul>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/a1d790b6-1592-4831-9f7f-7ea4ee4136b1/image.png" alt=""></p>
<p>터미널 4</p>
<ul>
<li>rqt_graph 실행<pre><code>$ rqt_graph</code></pre><img src="https://velog.velcdn.com/images/gks970113-woo/post/5f0e69dd-bbcd-4018-a2f1-f5bde9bb560d/image.png" alt=""></li>
</ul>
<h2 id="pubpy-생성-1">pub.py 생성</h2>
<pre><code>#! /usr/bin/env python

import rospy
from turtlesim.msg import Pose

def callback(data) :
    s = &quot;Location: %.2f, %.2f&quot; % (data.x, data.y)
    rospy.loginfo(rospy.get_caller_id() + s)

rospy.init_node(&quot;my_listener&quot;, anonymous=True)
rospy.Subscriber(&quot; /turtle1/pose&quot;, Pose, callback)
rospy.spin()
</code></pre><ul>
<li>마찬가지로 my_pkg1/src 위치에서 sub.py라는 이름으로 프로그램 작성</li>
<li>실행 권한을 sub.py에게 부여하고 pub.py와 turtlesim_node가 실행되는 상태에서 rosrun </li>
</ul>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/40c03f73-4794-423c-81a6-611214b0dfc5/image.png" alt=""></p>
<h1 id="roslaunch란">roslaunch란?</h1>
<p>하나 이상의 노드를 실행하고 노드 간의 통신을 설정하도록 하는 XML 파일이다.</p>
<pre><code>$ roslaunch [패키지 이름] [실행시킬 launch 파일 이름]</code></pre><p>이때 실행시킬 launch 파일은 반드시 패키지에 포함된 launch 파일이어야 한다</p>
<pre><code>&lt;launch&gt;
  &lt;node pkg=&quot;패키지 명(ex my_pkg1)&quot; type=&quot;노드가 포함된 소스파일 명(ex pub.py)&quot; name=&quot;노드 이름(ex pub_node)&quot; /&gt;
  &lt;node pkg=&quot;패키지 명(ex my_pkg1)&quot; type=&quot;노드가 포함된 소스파일 명(ex sub.py)&quot; name=&quot;노드 이름(ex sub_node)&quot; /&gt;
&lt;/launch&gt;</code></pre><p>launch 파일은 위와 같이 이루어져 있다</p>
<h2 id="launch-파일의-위치">launch 파일의 위치</h2>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/018ef71a-5791-47ec-bd5a-f19adeb50b38/image.png" alt=""></p>
<p>launch 파일은 반드시 패키지에 포함되어야 하기 때문에 Package 아래 launch 폴더에 존재한다</p>
<pre><code>$ cd ~/xycar_ws/src/my_pkg1
$ mkdir launch
$ cd ~/xycar_ws/src/my_pkg1/launch
$ gedit pub-sub.launch
$ cm
$ roslaunch my_pkg1 pub-sub.launch</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[ROS_3) ROS 세팅 & 기본 구조]]></title>
            <link>https://velog.io/@gks970113-woo/ROS3-ROS-%EC%84%B8%ED%8C%85-%EA%B8%B0%EB%B3%B8-%EA%B5%AC%EC%A1%B0</link>
            <guid>https://velog.io/@gks970113-woo/ROS3-ROS-%EC%84%B8%ED%8C%85-%EA%B8%B0%EB%B3%B8-%EA%B5%AC%EC%A1%B0</guid>
            <pubDate>Sat, 22 Apr 2023 16:15:19 GMT</pubDate>
            <description><![CDATA[<h2 id="ros-설치">ROS 설치</h2>
<pre><code class="language-bash">$ sudo sh -c &#39;echo&#39; &quot;deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main&quot; &gt; /etc/apt/sources.list.d/ros-latest.list&#39;
$ cat /etc/apt/sources.list.d/ros-latest.list
//ROS 제공하는 Software Repository 등록

$ sudo apt-key adv --keyserver &#39;hkp://keyserver.ubuntu.com:80&#39; --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654
//apt key 셋업

$ sudo apt-get update
$ sudo apt install ros-melodic-desktop-full
//패키지 설치

$ sudo apt install python-rosdepsudo rosdep initrosdep update
$ sudo rosdep init
$ rosdep update
//rosdep 초기화

$ echo &quot;source /opt/ros/melodic/setup.bash&quot; &gt;&gt; ~/.bashrc
$ source ~/.bashrc
//쉘 환경설정

$ sudo apt install python-rosinstall python-rosinstall-generator python-wstool build-essential
//추가로 필요한 도구 등 설치</code></pre>
<h2 id="ros-설치-확인">ROS 설치 확인</h2>
<pre><code class="language-bash">$ roscore

$ rosnode list
//roscore 실행한 터미널과 다른 터미널에서 실행(/rosout 이 나온다)</code></pre>
<hr>
<h2 id="ros-코딩을-위해-workspace-만들기">ROS 코딩을 위해 Workspace 만들기</h2>
<pre><code class="language-bash">$ cd
//Home 폴더 이동
$ mkdir -p ~/xycar_ws/src
//서브 폴더 생성
$ cd xycar_ws
//xycar_ws 폴더로 이동
$ catkin_make
//ROS 코딩 환경 셋업, 정리(빌드)</code></pre>
<h3 id="1-현재-workspace-구조">1. 현재 Workspace 구조</h3>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/a1cc3749-239b-494a-8b06-2b1f1deee9a2/image.png" alt=""></p>
<p>다음과 같은 Workspace 구조가 만들어 진다</p>
<h3 id="2-catkin_make-명령어-작성-이후-구조">2. catkin_make 명령어 작성 이후 구조</h3>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/90c09ec4-ea1e-4f59-9596-97d102b2add8/image.png" alt=""></p>
<p>catkin_make 작업을 통해 패키지를 빌드한다. 필요한 패키지들을 알아서 찾아 설치하고 바이너리 파일을 생성해 노드를 만들 수 있도록 세팅해준다. 밥먹기 전에 수저 물 놓은 세팅 작업같은 것</p>
<hr>
<h2 id="ros-작업환경-설정">ROS 작업환경 설정</h2>
<pre><code class="language-bash">$ cd
$ sudo gedit ~/.bashrc
//bashrc 파일을 열어서 수정하겠다는 의미
$ source .bashrc
//수정한 내용을 시스템에 반영하겠다(source)
$ printenv | grep ROS
// ROS 작업에 필요한 환경변수 설정을 확인할 수 있음</code></pre>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/dabcf0b0-71ff-480b-b9cd-0ce58dc88993/image.png" alt=""></p>
<p>bash 파일 맨 뒤에다가 적어서 설정내용을 바꿔주자</p>
<hr>
<h2 id="ros-패키지package">ROS 패키지(Package)</h2>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/70d4f79a-947d-4523-bf4e-429b64d64f87/image.png" alt=""></p>
<p>패키지는 ROS에서 개발되는 소프트웨어를 하나의 논리적 묶음으로 만든 것이다
예를 들어 보행자가 앞에 있는지 없는지 보행자 추적 시스템을 만든다고 하면 &quot;보행자 추적 패키지&quot; 라는 이름으로 하나의 프로젝트 처럼 만들어 관리할 수 있게 된다</p>
<h3 id="1-ros-패키지-만들기">1. ROS 패키지 만들기</h3>
<pre><code class="language-bash">$ cd ~/xycar_ws/src
//위의 그림처럼 프로젝트 폴더에 src 폴더에 들어온다
$ catkin_create_pkg my_pkg1 std_msgs rospy
// my_pkg1 이라는 이름의 패키지를 새로 만들고 패키지가 의존하고 있는 다른 패키지들을 나열한다</code></pre>
<h3 id="2-ros-패키지-빌드">2. ROS 패키지 빌드</h3>
<pre><code class="language-bash">$ cd ~/xycae_ws
$ catkin_make
//패키지 빌드

$ rospack find my_pkg1
$ rospack depends1 my_pkg1
$ roscd my_pkg1
//만들어진 패키지 확인 코드</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[자율주행 자동차 기술_2]]></title>
            <link>https://velog.io/@gks970113-woo/%EC%9E%90%EC%9C%A8%EC%A3%BC%ED%96%89-%EC%9E%90%EB%8F%99%EC%B0%A8-%EA%B8%B0%EC%88%A02</link>
            <guid>https://velog.io/@gks970113-woo/%EC%9E%90%EC%9C%A8%EC%A3%BC%ED%96%89-%EC%9E%90%EB%8F%99%EC%B0%A8-%EA%B8%B0%EC%88%A02</guid>
            <pubDate>Thu, 20 Apr 2023 05:40:41 GMT</pubDate>
            <description><![CDATA[<h2 id="autoware">Autoware</h2>
<ul>
<li>오픈 소스로 제공되는 자율주행차량 소프트웨어 플랫폼</li>
<li>자율주행차량 개발에 필요한 기능과 알고리즘을 제공하며 연구자와 엔지니어들이 자율주행 기술을 개발하고 실험하는 데 사용</li>
<li>SAE-레벨2</li>
<li>실차에 바로 적용 가능한 솔루션</li>
<li>30개 이상의 국가에서 사용</li>
<li>100개 이상의 회사들 사용</li>
<li>20개 이상의 차량 모델에 탑재</li>
</ul>
<h3 id="autoware의-구조도">Autoware의 구조도</h3>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/a791f7d2-2324-4cea-8474-40691589d577/image.png" alt=""></p>
<p>Sensing
다양한 센서를 지원하고 주변 환경에 대한 정보를 수집하며 차량의 상태와 주변의 장애물, 도로 표시, 교통 신호등을 인식
여러 센서들을 이용해 데이터를 수집하고 처리한다</p>
<p>Computing
sensing을 통해 수집된 데이터를 기반으로 인지, 제어, 결정의 과정을 반복하며 계산 작업을 수행한다</p>
<p>Actuation
차량의 Actuator(스로틀, 브레이크, 스티어링 등)을 제어하기 위한 명령을 생성 전달
제어 알고리즘을 통해 제어 입력을 생성해 속도, 방향, 가속도 등을 조절하고 생성된 경로를 따라 움직이도록 조절</p>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/ca420d50-f85e-42ee-9962-b16d9cf825b4/image.png" alt=""></p>
<hr>
<h2 id="자율주행-필수-요소-기술">자율주행 필수 요소 기술</h2>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/25b5e9f4-4d92-47c4-8404-9607b47c0de7/image.png" alt=""></p>
<h3 id="1-자율주행-알고리즘">1) 자율주행 알고리즘</h3>
<p>센싱(Sensing)</p>
<ul>
<li>주변정보 획득
GPS
IMU
라이다
초음파
카메라</li>
</ul>
<p>인지(Perception)</p>
<ul>
<li><p>Localization 자기 위치 파악
GPS와 IMU를 조합해서 위치 측정(위치 예측과 업데이트 반복)
Stereo 카메라 영상으로 위치 측정
라이다, 포인트 클라우드, 파티클 필터로 위치 측정
여러 센서를 융합해 정확도 개선</p>
</li>
<li><p>Object Detection(인식)
CNN 딥러닝 기반의 인식모델 사용</p>
</li>
<li><p>Object Tracking(추적)
개체 이동궤적(trajectory)을 추적
차량, 보행자와의 충돌 회피에 활용</p>
</li>
</ul>
<p>의사결정(Decision)</p>
<ul>
<li><p>동작 예측
다른 차량의 동작을 예측
확률 모델 만들고 확률 분포 구하기</p>
</li>
<li><p>경로 계획
Cost function으로 최적 경로 탐색
계산량 줄이기 위해 확률 기법 적용</p>
</li>
<li><p>장애물 회피(충돌 방지)
1단계 능동형 충돌까지의 시간과 최소거리 추정치 뽑아 경로 다시 계획
2단계 반응형 이동경로상에 장애물이 있으면 주행제어 시스템에 개입</p>
</li>
</ul>
<h3 id="2-자율주행-클라이언트-시스템">2) 자율주행 클라이언트 시스템</h3>
<p>소프트웨어</p>
<ul>
<li><p>실시간성과 신뢰성 확보 필요</p>
</li>
<li><p>ROS 문제점 해결 필요
Master가 죽으면 전체 시스템 다운되며 복구 용도의 모니터가 없음
메시지를 브로드캐스팅 하면서 성능이 저하, 멀티캐스팅 메커니즘 적용하면 좋음
노드가 해킹되기 쉽다 -&gt; 리눅스 컨테이너, 샌드박스로 보안 기능 강화 가능하다
로컬에서는 TCP/IP 통신 대신 공유 메모리 통신 방식을 적용하면 좋다</p>
</li>
</ul>
<p>하드웨어</p>
<ul>
<li>성능 향상 필요
파이프라인 병렬 프로세싱 기능 필요
HW 가성비 좋게 만들어야함
차량의 배터리 문제가 있으므로 전력 소모량 최소화 노력 필요
차량이라는 환경에서 발열 문제 심각 
발열을 최소화 하거나 열을 쉽게 배출시킬 방법을 강구</li>
</ul>
<h3 id="3-자율주행-클라우드-플랫폼">3) 자율주행 클라우드 플랫폼</h3>
<p>분산 컴퓨팅</p>
<ul>
<li><p>시뮬레이션 
ROS Bag/Replay
분산 환경으로 처리</p>
</li>
<li><p>HD Map 생성
원본데이터 처리
포인트 클라우드 생성 및 정렬
2D 반사맵 생성
HD맵 레이블링</p>
</li>
</ul>
<p>분산 스토리지</p>
<ul>
<li>딥러닝 모델 학습
학습데이터 준비
학습 진행
모델의 유효성과 효율성을 지속적으로 업데이트</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[자율주행 자동차 기술_1]]></title>
            <link>https://velog.io/@gks970113-woo/%EC%9E%90%EC%9C%A8%EC%A3%BC%ED%96%89-%EC%9E%90%EB%8F%99%EC%B0%A8-%EA%B8%B0%EC%88%A0-iql9srwj</link>
            <guid>https://velog.io/@gks970113-woo/%EC%9E%90%EC%9C%A8%EC%A3%BC%ED%96%89-%EC%9E%90%EB%8F%99%EC%B0%A8-%EA%B8%B0%EC%88%A0-iql9srwj</guid>
            <pubDate>Thu, 20 Apr 2023 05:12:53 GMT</pubDate>
            <description><![CDATA[<h2 id="자율주행-process">자율주행 Process</h2>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/22365dd7-36fc-4ee4-b74b-eec974f035ee/image.png" alt=""></p>
<h2 id="localization">Localization</h2>
<p>로봇이나 자율주행차량이 주어진 공간(Map)의 어디에 있는지 예측하는 방법
위치를 측정해서 확률을 업데이트하고 움직이는 과정의 반복
정밀지도와 연동하여 차량의 현재 위치를 파악한다</p>
<ul>
<li>라이다, 카메라를 이용</li>
</ul>
<hr>
<h2 id="global-path-planningroute-planning">Global Path Planning(Route Planning)</h2>
<p>목적지까지의 경로 찾기</p>
<ul>
<li>중간 목적지 또는 최종 목적지까지의 경로 </li>
<li>교차로에서의 행위도 결정</li>
<li>최소 비용, 최단 거리, 단순 정도에 따라 경로를 선택한다</li>
</ul>
<hr>
<h2 id="local-path-planningtrajectory-planning">Local Path Planning(Trajectory Planning)</h2>
<p>다음 이동할 곳으로의 경로 찾기(충돌 회피 고려)</p>
<ul>
<li>여러 개의 후보 경로 확보</li>
<li>끊임 없이 후보를 삭제하고 신규 후보 등록 작업을 반복한다</li>
<li>실시간으로 주변 정보를 처리하며 시스템 최적화가 필요하다</li>
</ul>
<ol>
<li>주행 환경 인식</li>
</ol>
<ul>
<li>센서를 사용해 주변 환경을 인식하고 정적 및 동적 장애물에 대한 정보를 수집</li>
<li>Lidar, 레이더, 카메라, 초음파센서 등 다양한 센서 사용</li>
</ul>
<ol start="2">
<li>비용 맵 생성</li>
</ol>
<ul>
<li>수집된 데이터를 기반으로 장애물을 포함하는 비용 맵 생성</li>
<li>장애물의 거리에 따라 다른 값을 가지며 이동 플랫폼이 안전한 경로를 계획할 수 있도록 도움을 줌</li>
</ul>
<ol start="3">
<li>경로 검색</li>
</ol>
<ul>
<li>비용 맵을 사용해 시작점에서 목표 지점까지의 경로를 계획</li>
<li>A*탐색, Dijkstra 알고리즘, RRT(Rapidly-exploring Random Trees) 등이 있다.</li>
</ul>
<ol start="4">
<li>경로 스무딩</li>
</ol>
<ul>
<li>계획된 경로의 불필요한 움직임을 최소화하고 부드러운 움직임을 위한 작업</li>
<li>최소 곡률 궤적, 스플라인 보간법 등을 사용</li>
</ul>
<ol start="5">
<li>속도 프로파일 생성</li>
</ol>
<ul>
<li>경로에 따라 이동 플랫폼의 속도 및 가속도 프로파일 생성</li>
<li>플랫폼이 안전하고 효율적으로 목표 지점까지 도달할 수 있도록함</li>
</ul>
<hr>
<h2 id="object-detection">Object Detection</h2>
<p>주변 차량, 보행자, 오토바이, 자전거 등을 인식</p>
<h2 id="object-tracking">Object Tracking</h2>
<p>각 오브젝트에 고유 ID 부여하여 추적, 예상되는 주행경로 예측</p>
<hr>
<h2 id="behavior-selector">Behavior Selector</h2>
<p>주어진 상황에 적합한 동작과 전략을 선택하는 행위
주변환경의 정보와 시스템의 목표를 고려해 가능한 동작 중 최적의 동작을 수행한다
일반 주행, 차선 변경, 회전, 긴금 정지 등 적절한 것을 결정하고 실행할 수 있는 경로 및 제어 명령을 생성한다</p>
<ol>
<li>환경 정보 수집</li>
</ol>
<ul>
<li>센서와 인식 시스템을 통해 주변 환경에 대한 정보를 수집</li>
<li>정적 장애물, 동적 장애물, 도로 조건, 교통 흐름 등을 포함</li>
</ul>
<ol start="2">
<li>상태 추정</li>
</ol>
<ul>
<li>수집된 정보를 사용하여 시스템의 현재 상태를 추정</li>
<li>상태 추정은 차량의 위치, 속도, 가속도, 주변 차량 및 보행자의 상태 등을 포함</li>
</ul>
<ol start="3">
<li>동작 후보 생성</li>
</ol>
<ul>
<li>가능한 동작 후보를 생성</li>
<li>시스템의 목표와 주변 환경에 따라 계속해서 달라짐</li>
</ul>
<ol start="4">
<li>비용 함수 계산</li>
</ol>
<ul>
<li>각 동작 후보에 대해 비용 함수를 계산 </li>
<li>비용 함수는 동작의 안전성, 효율성, 법규 준수 등 여러 요소를 고려하여 적절한 동작을 평가</li>
</ul>
<ol start="5">
<li>최적 동작 선택</li>
</ol>
<ul>
<li>비용 함수를 기반으로 최적의 동작을 선택</li>
<li>최적 동작은 비용이 가장 낮은 동작이며, 이를 통해 시스템은 상황에 맞게 적절한 동작을 수행할 수 있음</li>
</ul>
<hr>
<h2 id="local-path-following">Local Path Following</h2>
<p>Local Path Planning에서 생성된 경로를 따라 움직이는 기술
경로의 불연속성과 곡률을 최소화 하며 주어진 환경에서 효율적이고 안전한 이동을 보장하기 위해 설계</p>
<ol>
<li>경로 표현</li>
</ol>
<ul>
<li>로컬 경로는 일반적으로 연속적인 점들, 다항식, 스플라인 등의 수학적 표현으로 나타낸다</li>
<li>위와 같은 구성 성분으로 경로의 모양과 곡률을 명확하게 정의하고 시스템에 필요한 제어 입력을 계산할 수 있음</li>
</ul>
<ol start="2">
<li>제어 입력 계산</li>
</ol>
<ul>
<li>시스템의 현재 상태(위치, 속도, 방향 등)와 목표 경로를 고려해 이동 플랫폼이 경로를 정확하게 따르도록 하는 제어 입력 계산</li>
<li>제어 입력은 속도, 가속도, 회전률 등의 형태로 표현</li>
<li>시스템은 목포 경로에 대한 오차를 최소화할 수 있도록 함</li>
</ul>
<ol start="3">
<li>오차 수정</li>
</ol>
<ul>
<li>Local Path Following 중에는 목포 경로에서 벗어날 수 있는데 이 경루 시스템은 오차를 감지하고 수정하기 위해 알맞은 제어 입력을 적용해야 한다</li>
<li>피드백 제어, 피드포워드 제어 둘의 조합을 사용해 오차를 수정</li>
</ul>
<ol start="4">
<li>동적 장애물 대응</li>
</ol>
<ul>
<li>Local Path Following 중에 동적 장애물이 경로에 진입하면 장애물을 감지하고 회피</li>
<li>경로를 수정하거나 새로운 경로를 생성하여 회피 동작 수행</li>
</ul>
<p>Local Path Following Algorithm</p>
<ul>
<li><p>Pure Pursuit, Vector Field Histogram (VFH), Dynamic Window Approach(DWA) 등</p>
</li>
<li><p>Pure Pursuit 알고리즘
차량의 현재 위치를 결정
차량에서 가장 가까운 경로상의 점을 찾는다
목표점을 찾는다
곡률을 계산하고 해당 곡률로 차량의 방향을 업데이트 해준다
차량의 위치를 업데이트 한다</p>
</li>
</ul>
<hr>
<h2 id="veichle-control">Veichle Control</h2>
<p>원하는 방향으로 운동 상태를 조절하는 기술</p>
<ol>
<li>센싱 및 인식</li>
</ol>
<ul>
<li>차량의 센서(카메라, 라이다, 레이터, 초음파 센서 등)를 사용하여 주변 환경에 대한 정보를 수집하고 차량의 상태를 인식</li>
<li>차량의 위치, 속도, 방향, 주변 장애물의 위치롸 움직임 정보 포함</li>
</ul>
<ol start="2">
<li>경로 계획 및 추종</li>
</ol>
<ul>
<li>차량 제어 시스템은 Global Path Planning으로 부터 전달 받은 경로를 Local Path Planning, Path Planning 알고리즘을 통해 따라가도록 한다</li>
</ul>
<ol start="3">
<li>제어 알고리즘 </li>
</ol>
<ul>
<li>차량 제어 시스템은 제어 알고리즘을 사용해 차량의 속도, 방향, 가속도 등을 조절</li>
<li>PID(Proportional-Integral-Derivative)제어, Model Predictive Control(MPC), LQR(Linear Quadratic Regulator)등이 있다</li>
</ul>
<ol start="4">
<li>엑추에이터 제어</li>
</ol>
<ul>
<li>제어 알고리즘을 통해 생성된 제어 입력은 차량의 엑추에이터(스로틀, 브레이크, 스티어링 등)를 제어하는데 사용된다</li>
<li>이 과정으로 차량은 원하는 속도와 방향으로 움직이게 된다</li>
</ul>
<ol start="5">
<li>안전 및 긴급 상황 대응</li>
</ol>
<ul>
<li>Veichle Control은 긴급 상황에 대비해 안전 기능을 포함</li>
<li>장애물이 갑자기 나타날때 급제동을 하거나 경로를 이탈했을때 안전한 상태로 돌릴 수 있도록 조취를 취함</li>
<li>안전한 상태를 유지하기 위해 센서 데이터를 실시간으로 모니터링하고 Local Path Follwing 처럼 잠재적 위험을 감지하고 회피 동작을 수행</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[자율주행 자동차 개념]]></title>
            <link>https://velog.io/@gks970113-woo/%EC%9E%90%EC%9C%A8%EC%A3%BC%ED%96%89-%EC%9E%90%EB%8F%99%EC%B0%A8-%EA%B8%B0%EC%88%A0</link>
            <guid>https://velog.io/@gks970113-woo/%EC%9E%90%EC%9C%A8%EC%A3%BC%ED%96%89-%EC%9E%90%EB%8F%99%EC%B0%A8-%EA%B8%B0%EC%88%A0</guid>
            <pubDate>Thu, 20 Apr 2023 04:26:15 GMT</pubDate>
            <description><![CDATA[<h3 id="자율주행자동차">자율주행자동차</h3>
<p>운전자 또는 승객의 조작 없이 자동차 스스로 운행이 가능한 자동차를 말한다</p>
<br/>

<h3 id="자율주행-6단계">자율주행 6단계</h3>
<p>미국 자동차기술학회(SAE)는 자동 주행 자동차 기술을 6단계로 구분했다</p>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/d248a758-9142-43a3-8b47-e6fc2892d396/image.png" alt=""></p>
<blockquote>
<p>출처 도로교통부</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/0652a5fd-5d26-48f0-8f11-758d481d8e7a/image.png" alt=""></p>
<blockquote>
<p>출처 현대자동차</p>
</blockquote>
<br/>

<h3 id="자율주행-3단계-프로세스">자율주행 3단계 프로세스</h3>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/d0d7506c-5027-4045-968e-5a61d1e37bf6/image.png" alt=""></p>
<blockquote>
<p>출처 현대자동차</p>
</blockquote>
<br/>

<h3 id="고정밀-지도hd-map">고정밀 지도(HD Map)</h3>
<p>HD Map(High Definition Map)은 주변환경 정보가 3D로 구현된 지도로 오차 범위가 10~20cm 밖에 되지 않아 기존 지도보다 10배 이상의 높은 정확성을 가지고 있다
차선 정보, 가드레일, 도로 곡률, 경사, 신호등 위치, 교통 표식과 같은 다양한 부가정보를 포함</p>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/04cef788-6812-4ab8-ba33-ab762b9821c9/image.png" alt=""></p>
<blockquote>
<p>출처 Mapbox blog</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/e742960a-8a5e-4a01-a2c2-8fc43645b542/image.png" alt=""></p>
<p>HD Map을 사용해서 벡터맵과 포인트맵을 같이 나타낸 형태</p>
<br/>


<h3 id="고정밀-지도의-제작">고정밀 지도의 제작</h3>
<p>MMS(Mobile Mapping System)</p>
<ul>
<li>데이터를 수집한 다음 후처리 작업을 통해 지도를 제작</li>
</ul>
<p><img src="https://velog.velcdn.com/images/gks970113-woo/post/9a8e8b78-be07-48ea-ab29-c199b6507c76/image.png" alt=""></p>
<blockquote>
<p>출처 In1Go Technologies Inc</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[C/C++] stringstream 사용법]]></title>
            <link>https://velog.io/@gks970113-woo/CC-stringstream-%EC%82%AC%EC%9A%A9%EB%B2%95</link>
            <guid>https://velog.io/@gks970113-woo/CC-stringstream-%EC%82%AC%EC%9A%A9%EB%B2%95</guid>
            <pubDate>Wed, 19 Apr 2023 16:25:17 GMT</pubDate>
            <description><![CDATA[<h1 id="stringstream">stringstream</h1>
<h3 id="개념">개념</h3>
<p>C++의 표준 라이브러리의 일부로 &#39;sstream&#39; 헤더 파일에 정의 되어있다. 문자열 스트림으로 작동하며, 일반적인 입출력 스트림처럼 사용할 수 있다.
&#39;stringstream&#39;은 문자열을 읽거나 쓸 때 편리한 방법을 제공하고 문자열로부터 값을 추출하거나 문자열에 값을 삽입할때 사용한다</p>
<h3 id="선언법">선언법</h3>
<pre><code class="language-cpp">#include &lt;sstream&gt;
</code></pre>
<p>stringstream을 사용하기 위해 sstream 헤더 파일을 포함</p>
<pre><code class="language-cpp">std::istringstream inputStringStream;
std::ostringstream outputStringStream;
std::stringstream stringStream;
</code></pre>
<p>istringstream은 입력 스트림으로만
ostringstream은 출력 스트림으로만
stringstream은 입력과 출력 스트림으로 작동한다</p>
<h3 id="istringstream">istringstream</h3>
<ul>
<li>istringstream은 input string stream의 약자</li>
<li>입력 문자열에서 데이터를 읽어오는데 사용</li>
<li>자연스럽게 공백이나 개행문자를 제거하고 원하는 데이터 형태의 문자열만 읽을 수 있다는 장점</li>
</ul>
<p>예제</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;sstream&gt;
#include &lt;string&gt;

int main() {
    std::string input_string = &quot;10 20 30 40 50&quot;;
    std::istringstream iss(input_string);

    int num;
    while (iss &gt;&gt; num) {
        std::cout &lt;&lt; &quot;Read number: &quot; &lt;&lt; num &lt;&lt; std::endl;
    }

    return 0;
}
</code></pre>
<p>결과</p>
<pre><code>Read number: 10
Read number: 20
Read number: 30
Read number: 40
Read number: 50
</code></pre><h3 id="ostringstream">ostringstream</h3>
<ul>
<li>output string stream의 약자</li>
<li>데이터를 문자열로 출력하는데 사용된다</li>
<li>ostringstream 객체를 사용해 여러 자료형을 문자열로 합쳐준다</li>
<li>to_string() 함수를 이용해 문자열이 아닌 여러 자료형들을 문자열로 바꾸고 + 해주는 작업을 한번에 처리한다고 보면 됨</li>
<li>잘 사용하지는 않을 것 같음</li>
</ul>
<p>예제</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;sstream&gt;
#include &lt;string&gt;

int main() {
    std::ostringstream oss;

    int num1 = 42;
    double num2 = 3.14;
    std::string str = &quot;Hello, C++!&quot;;

    oss &lt;&lt; &quot;Integer: &quot; &lt;&lt; num1 &lt;&lt; &quot;, Double: &quot; &lt;&lt; num2 &lt;&lt; &quot;, String: &quot; &lt;&lt; str;

    std::string result = oss.str();
    std::cout &lt;&lt; result &lt;&lt; std::endl;

    return 0;
}
</code></pre>
<p>결과</p>
<pre><code>Integer: 42, Double: 3.14, String: Hello, C++!</code></pre><h3 id="stringstream-1">stringstream</h3>
<ul>
<li>입출력 스트림을 모두 다룰 수 있는 객체</li>
<li>istringstream, ostringstream 기능을 둘 다 포함하고 있다</li>
<li>원하는 문자열을 기준으로 문자열을 나눌 수 있음</li>
<li>공백과 개행문자를 빼고 문자열만 뽑아낼 수 있음</li>
<li>문자열에 여러 자료형을 추가해서 문자열로 변환해 읽고 쓸 수 있음</li>
</ul>
<p><br>예제(공백과 개행문자를 제거해 문자열 나누기)</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;sstream&gt;
#include &lt;string&gt;

int main() {
    std::string input_string = &quot;Token1 Token2 Token3\nToken4 Token5&quot;;
    std::stringstream ss(input_string);

    std::string token;
    while (ss &gt;&gt; token) {
        std::cout &lt;&lt; &quot;Token: &quot; &lt;&lt; token &lt;&lt; std::endl;
    }

    return 0;
}
</code></pre>
<p>결과</p>
<pre><code>Token: Token1
Token: Token2
Token: Token3
Token: Token4
Token: Token5</code></pre><p><br>예제(특정 문자를 기준으로 문자열 나누기)</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;sstream&gt;
#include &lt;string&gt;

int main() {
    std::string input_string = &quot;Item1|Item2|Item3&quot;;
    char delimiter = &#39;|&#39;;
    std::stringstream ss(input_string);

    std::string token;
    while (getline(ss, token, delimiter)) {
        std::cout &lt;&lt; &quot;Token: &quot; &lt;&lt; token &lt;&lt; std::endl;
    }

    return 0;
}</code></pre>
<p>결과</p>
<pre><code>Token: Item1
Token: Item2
Token: Item3
</code></pre>]]></description>
        </item>
    </channel>
</rss>