<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>seolgu Today</title>
    <link>https://seolgu.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Sat, 5 Sep 2026 08:34:30 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>seolgugu</managingEditor>
    <item>
      <title>라즈베리파이4 + OpenWrt로 방화벽 구축하기 (feat. iptime U1G)</title>
      <link>https://seolgu.tistory.com/30</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;쿠버네티스 클러스터도 있겠다,&amp;nbsp;&lt;br&gt;혼자 해볼 수 있는 수준의 웹서비스와 마이크로서비스는 웬만큼 해본것 같았기에 뭐 더 할게 없나 찾아보던 중,&lt;br&gt;라즈베리파이 하나를 방화벽으로 만들면 재밌겠다는 생각이 들었다.&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;방화벽이 뭔지도 모르고있었지만, 서버랙에 방화벽이랍시고 서버랑 똑같은 크기의 무언가가 들어가는걸 보고 뭔지 궁금해졌고&amp;nbsp;&lt;br&gt;그래서 직접 만들어보려고 한다.&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;일단 k3s 클러스터만 담당하는 방화벽으로 할 생각이라,&amp;nbsp;&lt;br&gt;공유기(라우터) -&amp;gt; 방화벽 -&amp;gt; 클러스터 의 순서로 구성할 예정이다.&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;파이의 내장 랜 포트는 WAN으로,&lt;br&gt;LAN은 USB 포트에 유선랜카드를 연결할 생각이다.&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;세팅 과정&lt;/p&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 부팅 이미지 굽기&lt;/h3&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;&lt;a href=&quot;https://firmware-selector.openwrt.org/&quot; target=&quot;_blank&quot;&gt;&lt;span&gt;https://firmware-selector.openwrt.org/&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;figure data-ke-type=&quot;opengraph&quot; data-og-title=&quot;OpenWrt Firmware Selector&quot; data-ke-align=&quot;alignCenter&quot; data-og-description=&quot;العربية (Arabic) Asturianu (Asturian) български (Bulgarian) বাংলা (Bengali) Català (Catalan) Čeština (Czech) Dansk (Danish) Deutsch (German) Ελληνικά (Greek) English Español (Spanish) فارسی (Persian) Suomalainen (&quot; data-og-host=&quot;firmware-selector.openwrt.org&quot; data-og-source-url=&quot;https://firmware-selector.openwrt.org/&quot; data-og-url=&quot;https://firmware-selector.openwrt.org/&quot;&gt;&lt;a href=&quot;https://firmware-selector.openwrt.org/&quot; target=&quot;_blank&quot; data-source-url=&quot;https://firmware-selector.openwrt.org/&quot;&gt;&lt;div class=&quot;og-image&quot;&gt;&lt;/div&gt;&lt;div class=&quot;og-text&quot;&gt;&lt;p class=&quot;og-title&quot;&gt;OpenWrt Firmware Selector&lt;/p&gt;&lt;p class=&quot;og-desc&quot;&gt;العربية (Arabic) Asturianu (Asturian) български (Bulgarian) বাংলা (Bengali) Català (Catalan) Čeština (Czech) Dansk (Danish) Deutsch (German) Ελληνικά (Greek) English Español (Spanish) فارسی (Persian) Suomalainen (&lt;/p&gt;&lt;p class=&quot;og-host&quot;&gt;firmware-selector.openwrt.org&lt;/p&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;위 링크에서 OpenWrt의 펌웨어 이미지 (Factory Ext4) 를 다운받는다.&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;그리고 Raspberry Pi Imager 프로그램에서&amp;nbsp;&lt;br&gt;OS 선택 -&amp;gt; Use Custom (사용자 지정) -&amp;gt; 다운로드한 &lt;b&gt;ext4 이미지&lt;/b&gt; 선택하고, 이미지를 디스크에 굽는다.&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 부팅 확인&lt;/h3&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;파이와 노트북을 랜선으로 연결한다.&lt;br&gt;이후 파이에 전원을 넣고 약 1분간 기다리고&lt;br&gt;노트북 브라우저에서 192.168.1.1 로 접속한다.&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;277&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bfufVX/dJMcadnqyot/FGtpKZN6GDgycsWkNJprUk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bfufVX/dJMcadnqyot/FGtpKZN6GDgycsWkNJprUk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bfufVX/dJMcadnqyot/FGtpKZN6GDgycsWkNJprUk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbfufVX%2FdJMcadnqyot%2FFGtpKZN6GDgycsWkNJprUk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;652&quot; height=&quot;277&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;277&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 위와같은 화면이 뜰텐데, 기본 비밀번호는 없으니 그냥 로그인버튼을 누르면 된다.&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 유선랜카드 드라이버 설치&lt;/h3&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;파이와 연결은 확인했으니 유선랜카드 드라이버를 다운로드 받아야하는데,&amp;nbsp;&lt;br&gt;지금 파이에는 인터넷이 없는 상태다.&amp;nbsp;&lt;br&gt;근데 지금 이걸 공유기에 연결하게된다면, 공유기에서 할당해주는 50번 대역의 ip와, OpenWrt 자체가 갖고있는 1번 대역의 ip가 충돌할것으로 예상되어 그냥 내 노트북 와이파이 인터넷을 파이쪽에 공유해주려고 한다.&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-1. 인터넷 설정&lt;/h3&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;제어판 &amp;gt; 네트워크 및 인터넷 &amp;gt; 네트워크 및 공유 센터 &amp;gt; 어댑터 설정 변경 으로 들어간다.&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1043&quot; data-origin-height=&quot;337&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dkheKt/dJMb996ryxy/8H5t60sAJuU1w6KadFXFn1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dkheKt/dJMb996ryxy/8H5t60sAJuU1w6KadFXFn1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dkheKt/dJMb996ryxy/8H5t60sAJuU1w6KadFXFn1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdkheKt%2FdJMb996ryxy%2F8H5t60sAJuU1w6KadFXFn1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1043&quot; height=&quot;337&quot; data-origin-width=&quot;1043&quot; data-origin-height=&quot;337&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 Wi-Fi를 우클릭해서 속성으로 들어간다.&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;407&quot; data-origin-height=&quot;310&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GviQU/dJMcaflhzTy/uPOqEYx8Wm4KSpr53QsNW0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GviQU/dJMcaflhzTy/uPOqEYx8Wm4KSpr53QsNW0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GviQU/dJMcaflhzTy/uPOqEYx8Wm4KSpr53QsNW0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGviQU%2FdJMcaflhzTy%2FuPOqEYx8Wm4KSpr53QsNW0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;407&quot; height=&quot;310&quot; data-origin-width=&quot;407&quot; data-origin-height=&quot;310&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 위처럼 공유 탭에서 허용을 눌러주고, 홈 네트워킹 연결은 이더넷으로 설정해준다.&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;788&quot; data-origin-height=&quot;612&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bj4YLM/dJMcaf6EhEO/uXcHIrnYi4arppyidpXSK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bj4YLM/dJMcaf6EhEO/uXcHIrnYi4arppyidpXSK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bj4YLM/dJMcaf6EhEO/uXcHIrnYi4arppyidpXSK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbj4YLM%2FdJMcaf6EhEO%2FuXcHIrnYi4arppyidpXSK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;643&quot; height=&quot;499&quot; data-origin-width=&quot;788&quot; data-origin-height=&quot;612&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 이번에는 이더넷을 우클릭해 속성을 들어간 뒤에,&amp;nbsp;&lt;br&gt;네트워킹 탭에서 인터넷 프로토콜 버전 4를 눌러 속성으로 들어간다.&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;458&quot; data-origin-height=&quot;512&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dsFACc/dJMcadOtAJZ/arvc1V0aoVtf13kjKiGPEk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dsFACc/dJMcadOtAJZ/arvc1V0aoVtf13kjKiGPEk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dsFACc/dJMcadOtAJZ/arvc1V0aoVtf13kjKiGPEk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdsFACc%2FdJMcadOtAJZ%2Farvc1V0aoVtf13kjKiGPEk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;458&quot; height=&quot;512&quot; data-origin-width=&quot;458&quot; data-origin-height=&quot;512&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사진처럼 노트북의 ip를 192.168.1.2 로 지정해주면 된다.&amp;nbsp;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-2. 파이에서 게이트웨이 지정&lt;/h3&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;983&quot; data-origin-height=&quot;483&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/biwdMY/dJMcabiUb81/xRvJWakUkC5MUlIxqYVwbk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/biwdMY/dJMcabiUb81/xRvJWakUkC5MUlIxqYVwbk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/biwdMY/dJMcabiUb81/xRvJWakUkC5MUlIxqYVwbk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbiwdMY%2FdJMcabiUb81%2FxRvJWakUkC5MUlIxqYVwbk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;785&quot; height=&quot;386&quot; data-origin-width=&quot;983&quot; data-origin-height=&quot;483&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;192.168.1.1 로 접속하고 로그인하면 위와같은 화면이 뜰 것이다.&amp;nbsp;&lt;br&gt;Network &amp;gt; Interfaces 로 들어간 후, 아래 화면에서 lan 옆의 Edit을 누른다.&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;977&quot; data-origin-height=&quot;458&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tHS5S/dJMcafZRRDU/wVLVE9haEM2CEXBkcOyork/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tHS5S/dJMcafZRRDU/wVLVE9haEM2CEXBkcOyork/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tHS5S/dJMcafZRRDU/wVLVE9haEM2CEXBkcOyork/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtHS5S%2FdJMcafZRRDU%2FwVLVE9haEM2CEXBkcOyork%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;977&quot; height=&quot;458&quot; data-origin-width=&quot;977&quot; data-origin-height=&quot;458&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;894&quot; data-origin-height=&quot;647&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dY7RAb/dJMcadOtA9d/xnpfwKkfeP9iRs7Vd0ZQ8K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dY7RAb/dJMcadOtA9d/xnpfwKkfeP9iRs7Vd0ZQ8K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dY7RAb/dJMcadOtA9d/xnpfwKkfeP9iRs7Vd0ZQ8K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdY7RAb%2FdJMcadOtA9d%2FxnpfwKkfeP9iRs7Vd0ZQ8K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;780&quot; height=&quot;564&quot; data-origin-width=&quot;894&quot; data-origin-height=&quot;647&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br&gt;위 화면에서 IPv4 gateway 란에 192.168.1.2 를 입력하고,&lt;br&gt;&amp;nbsp;Advanced Settings 탭으로 들어가서 Custom DNS Server 를 8.8.8.8 로 입력하고 저장한다.&amp;nbsp;&lt;br&gt;반드시 save 누른 후 나오는 화면에서 save &amp;amp; apply도 눌러야 한다. 그래야 적용되기 때문&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-3. 윈도우 방화벽 해제&lt;/h3&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1114&quot; data-origin-height=&quot;629&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzfNa6/dJMb99ZHdjS/KxVb7ZklULvK1Pzq3OxKV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzfNa6/dJMb99ZHdjS/KxVb7ZklULvK1Pzq3OxKV1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzfNa6/dJMb99ZHdjS/KxVb7ZklULvK1Pzq3OxKV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbzfNa6%2FdJMb99ZHdjS%2FKxVb7ZklULvK1Pzq3OxKV1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1114&quot; height=&quot;629&quot; data-origin-width=&quot;1114&quot; data-origin-height=&quot;629&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;윈도우 검색창에 &lt;b&gt;'방화벽 상태 확인'&lt;/b&gt; 검색,&amp;nbsp;&lt;br&gt;좌측의 &lt;b&gt;'Windows Defender 방화벽 설정 또는 해제'&lt;/b&gt; 클릭해서 방화벽을 해제해준다.&amp;nbsp;&lt;br&gt;드라이버 설치 이후 다시 활성화하면 된다.&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-4. 드라이버 설치&lt;/h3&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;983&quot; data-origin-height=&quot;483&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/biwdMY/dJMcabiUb81/xRvJWakUkC5MUlIxqYVwbk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/biwdMY/dJMcabiUb81/xRvJWakUkC5MUlIxqYVwbk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/biwdMY/dJMcabiUb81/xRvJWakUkC5MUlIxqYVwbk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbiwdMY%2FdJMcabiUb81%2FxRvJWakUkC5MUlIxqYVwbk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;785&quot; height=&quot;386&quot; data-origin-width=&quot;983&quot; data-origin-height=&quot;483&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인터넷에 연결시킨 후, 192.168.1.1 로 접속하고 로그인하면 위와같은 화면이 뜰 것이다.&amp;nbsp;&lt;br&gt;여기서 상단의 System &amp;gt; Software 로 들어가서, 아래의 update lists 버튼을 누른다.&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;118&quot; data-origin-height=&quot;63&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BmwOb/dJMcagYMJRt/xGK1VhBVKfvQY9hDIDFhok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BmwOb/dJMcagYMJRt/xGK1VhBVKfvQY9hDIDFhok/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BmwOb/dJMcagYMJRt/xGK1VhBVKfvQY9hDIDFhok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBmwOb%2FdJMcagYMJRt%2FxGK1VhBVKfvQY9hDIDFhok%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;118&quot; height=&quot;63&quot; data-origin-width=&quot;118&quot; data-origin-height=&quot;63&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Error가 뜨지 않았다면, 아래와 같이 Filter에 kmod-usb-net-rtl8152 를 입력하고 install 버튼을 눌러 설치한다.&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;975&quot; data-origin-height=&quot;540&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9w9ED/dJMcahKbKW9/KgtZq8JLtdKAySbZZmV0rk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9w9ED/dJMcahKbKW9/KgtZq8JLtdKAySbZZmV0rk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9w9ED/dJMcahKbKW9/KgtZq8JLtdKAySbZZmV0rk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9w9ED%2FdJMcahKbKW9%2FKgtZq8JLtdKAySbZZmV0rk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;753&quot; height=&quot;417&quot; data-origin-width=&quot;975&quot; data-origin-height=&quot;540&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;설치하면 아래처럼 Network &amp;gt; Interfaces &amp;gt; Devices 에서 드디어 새로운 어댑터인 eth1 이 잡힌걸 확인할 수 있다!&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;971&quot; data-origin-height=&quot;485&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJuAFT/dJMcad109qK/tVbjKew799BbbzEh9fkOF0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJuAFT/dJMcad109qK/tVbjKew799BbbzEh9fkOF0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJuAFT/dJMcad109qK/tVbjKew799BbbzEh9fkOF0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJuAFT%2FdJMcad109qK%2FtVbjKew799BbbzEh9fkOF0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;806&quot; height=&quot;403&quot; data-origin-width=&quot;971&quot; data-origin-height=&quot;485&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;유선랜카드와 랜선이 연결되어있지 않고 유선랜카드만 연결해도 떠야한다.&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. WAN 인터페이스 만들기&lt;/h3&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;997&quot; data-origin-height=&quot;469&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Y8Cyu/dJMcacB6e95/XxXbboKUOYswbwIGjxi4t1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Y8Cyu/dJMcacB6e95/XxXbboKUOYswbwIGjxi4t1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Y8Cyu/dJMcacB6e95/XxXbboKUOYswbwIGjxi4t1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FY8Cyu%2FdJMcacB6e95%2FXxXbboKUOYswbwIGjxi4t1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;997&quot; height=&quot;469&quot; data-origin-width=&quot;997&quot; data-origin-height=&quot;469&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Network &amp;gt; Interfaces &amp;gt; Add new interface 로 들어간 후, 위처럼 wan (소문자), DHCP client, eth1를 지정한 후 create interface를 누른다.&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;973&quot; data-origin-height=&quot;448&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nh732/dJMcaibfYiG/dGag5lNky9oxzek3thiCsK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nh732/dJMcaibfYiG/dGag5lNky9oxzek3thiCsK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nh732/dJMcaibfYiG/dGag5lNky9oxzek3thiCsK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fnh732%2FdJMcaibfYiG%2FdGag5lNky9oxzek3thiCsK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;973&quot; height=&quot;448&quot; data-origin-width=&quot;973&quot; data-origin-height=&quot;448&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;create interface를 누르면 위와같은 창이 뜰텐데, Firewall Settings 탭으로 들어가 wan을 지정해준 후 save해준다.&amp;nbsp;&lt;br&gt;이후 save &amp;amp; apply도 눌러야 적용된다.&amp;nbsp;&lt;br&gt;&lt;br&gt;&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로젝트/셀프 호스팅</category>
      <author>seolgugu</author>
      <guid isPermaLink="true">https://seolgu.tistory.com/30</guid>
      <comments>https://seolgu.tistory.com/30#entry30comment</comments>
      <pubDate>Thu, 19 Feb 2026 23:24:08 +0900</pubDate>
    </item>
    <item>
      <title>갑자기 k3s 클러스터가 죽었다.</title>
      <link>https://seolgu.tistory.com/29</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1월 26일 밤 12시 30분경 부터 갑자기 서버에 접속이 안되기 시작했다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그냥 잘 돌고있나 확인차 ssh로 들어갔는데 응답이 없었고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ping을 날렸는데도 지연시간이 3000ms정도로 뜨다가&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러다가 결국 아예 연결이 끊겼는지 tailscale의 last seen 시간이 12시 39분으로 찍혀있는 상태로 완전 멈춰버렸다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주말동안 본가에 있던 나로서는 서버를 만질 수가 없었기에 평일에 서버가 있는 자취방으로 돌아와서 확인해본 결과,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 인터넷 모뎀에 문제가 있었는지 집 와이파이가 인터넷이 안되는 상태였고,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왜인지 마스터노드인 n100 미니pc는 랜선이 꽂혀있었음에도 공유기에 연결이 안되어있었다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아예 모니터를 연결하고 재부팅을 해주니 이젠 다시 정상적으로 네트워크도 연결이 되었고, 서비스들도 다시 돌아가기 시작했다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3426&quot; data-origin-height=&quot;717&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mL3XM/dJMcafFqgOM/5QX3NDHKnfhjPw6c5skWuk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mL3XM/dJMcafFqgOM/5QX3NDHKnfhjPw6c5skWuk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mL3XM/dJMcafFqgOM/5QX3NDHKnfhjPw6c5skWuk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmL3XM%2FdJMcafFqgOM%2F5QX3NDHKnfhjPw6c5skWuk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3426&quot; height=&quot;717&quot; data-origin-width=&quot;3426&quot; data-origin-height=&quot;717&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3417&quot; data-origin-height=&quot;1137&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pkw1h/dJMcaf6tGZy/VNotlKUpXAuH0qOq8vlXB1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pkw1h/dJMcaf6tGZy/VNotlKUpXAuH0qOq8vlXB1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pkw1h/dJMcaf6tGZy/VNotlKUpXAuH0qOq8vlXB1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fpkw1h%2FdJMcaf6tGZy%2FVNotlKUpXAuH0qOq8vlXB1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3417&quot; height=&quot;1137&quot; data-origin-width=&quot;3417&quot; data-origin-height=&quot;1137&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 인터넷만의 문제는 아니었던게, 서버 접속이 끊긴 12시 30분부터 정확하게 prometheus의 기록이 끊겨있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또 보면 죽기 직전까지 급격하게 디스크 사용량이 계단식으로 증가하는걸 볼 수 있는데,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;막상 집에 와서 접속해보니 디스크 상태는 너무 널널한 상태였다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;892&quot; data-origin-height=&quot;188&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XOMbO/dJMcagqMhHK/2Qm1Il8kBXsY5izS9UBS0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XOMbO/dJMcagqMhHK/2Qm1Il8kBXsY5izS9UBS0k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XOMbO/dJMcagqMhHK/2Qm1Il8kBXsY5izS9UBS0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXOMbO%2FdJMcagqMhHK%2F2Qm1Il8kBXsY5izS9UBS0k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;892&quot; height=&quot;188&quot; data-origin-width=&quot;892&quot; data-origin-height=&quot;188&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 crash라는 로그가 보이긴 하고,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디스크 사용량이 계단식으로 늘어났던게 좀 불안하긴 하지만, 원인을 찾을 수 없으니 할 수 있는 조치만 해보려고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;조치&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 커널 사망 -&amp;gt; 재부팅 설정&lt;/p&gt;
&lt;pre id=&quot;code_1769515028326&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 커널 패닉 발생 시 10초 후 자동 재부팅
echo &quot;kernel.panic = 10&quot; | sudo tee -a /etc/sysctl.conf
echo &quot;kernel.panic_on_oops = 1&quot; | sudo tee -a /etc/sysctl.conf
# 설정 즉시 적용
sudo sysctl -p&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 로그 보존 설정&lt;/p&gt;
&lt;pre id=&quot;code_1769515012743&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo mkdir -p /var/log/journal
sudo systemctl restart systemd-journald&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에는 로그가 남아있지 않았기 때문에 위 명령으로 메모리가 아닌 디스크에 영구 저장되도록 바꿔주었다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;계획&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 라즈베리파이 2대를 마스터로 돌려서 taint를 걸어둔 상태로 마스터노드가 3개인 HA모드로 구축해보려고 한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 그만큼 worker가 줄어들었으니 n100 미니pc의 taint를 해제해서 연산용으로 사용하면서, 마스터노드의 역할도 할 수 있도록 해줄 생각이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어차피 etcd 관리는 taint 걸린 파이 2대가 잘 해주지 않을까 싶다.&lt;/p&gt;</description>
      <category>프로젝트/셀프 호스팅</category>
      <category>k3s</category>
      <category>클러스터</category>
      <author>seolgugu</author>
      <guid isPermaLink="true">https://seolgu.tistory.com/29</guid>
      <comments>https://seolgu.tistory.com/29#entry29comment</comments>
      <pubDate>Tue, 27 Jan 2026 21:01:39 +0900</pubDate>
    </item>
    <item>
      <title>분산처리 프레임워크 메모리 누수 문제 해결</title>
      <link>https://seolgu.tistory.com/28</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;라즈베리파이 를 활용한 프레임워크의 구조를 배포 가능하게 바꾸고 서버에 배포하니 문제가 발생했다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에는 로컬에서 한번에 실행하고 화면 뜨는걸 확인하고 바로 껐기 때문에 문제를 못느꼈지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서버에서 24시간 돌아가게 해놓으니 메모리 누수 문제를 확인할 수 있었다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;발견 계기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;집에서 잘 돌아가고 있나 궁금해서 웹서버가 떠있는 주소로 접속했더니, 연결이 안됐다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클러스터에 설치해둔 grafana를 통해 확인해보니 k3s 노드 하나가 아래와 같은 상태였다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;789&quot; data-origin-height=&quot;264&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bs3aHI/dJMcacom3G8/B5VGd8qKZby22VJ6c87Ehk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bs3aHI/dJMcacom3G8/B5VGd8qKZby22VJ6c87Ehk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bs3aHI/dJMcacom3G8/B5VGd8qKZby22VJ6c87Ehk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbs3aHI%2FdJMcacom3G8%2FB5VGd8qKZby22VJ6c87Ehk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;789&quot; height=&quot;264&quot; data-origin-width=&quot;789&quot; data-origin-height=&quot;264&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메모리 사용량이 특정 시점부터 쭉 증가하다가 죽었고, 다시 켜지자마자 또 메모리 사용량이 쭉 증가하다가 죽기를 반복하고 있었다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1430&quot; data-origin-height=&quot;806&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bejhrc/dJMcadnd5DJ/6NxRXDtFxt1xMXlFFJGQR1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bejhrc/dJMcadnd5DJ/6NxRXDtFxt1xMXlFFJGQR1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bejhrc/dJMcadnd5DJ/6NxRXDtFxt1xMXlFFJGQR1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbejhrc%2FdJMcadnd5DJ%2F6NxRXDtFxt1xMXlFFJGQR1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;804&quot; height=&quot;453&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1430&quot; data-origin-height=&quot;806&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제를 파악하기 위해 prometheus 쿼리를 통해 메모리 사용량 상위 다섯개 파드를 확인해보니 바로 범인을 찾을 수 있었다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;범인&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 gateway 노드가 문제였다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;gateway node가 inteface들에 데이터를 쫙 뿌릴 때,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;web inteface에는 내부적으로 영상 끊김 방지를 위해 내장되어있는 Time Jitter Buffer(우선순위 큐)를 거친다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 그 buffer 내부적으로 최대 크기가 지정되어있지 않았고,&amp;nbsp;gateway에서는 web_interface의 buffer에 프레임을 계속해서 push한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 유일하게 buffer에서 pop하는 로직이 들어있는 stream_generator는 웹에 접속자가 있을때만 작동했기 때문에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 접속을 끊은 이후에는 buffer에서 pop이 이루어지지 않는것이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;buffer_delay값이 존재하긴 했지만, pop할때만 delay 안쪽에 있는 프레임들을 pop되지 않게만 해주는 역할일 뿐,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;buffer가 넘치지 않게 막아주는 역할은 해주지 못했다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;해결&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 push 메소드에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;버퍼 최대 크기를 넘었다면 최대 크기 이하일때까지 pop을 진행하고, 그 이후에 push하도록 로직을 추가해주었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;451&quot; data-origin-height=&quot;163&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cuhyX0/dJMcagYAkjC/08yBfW3I4UVKRIVPszDb01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cuhyX0/dJMcagYAkjC/08yBfW3I4UVKRIVPszDb01/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cuhyX0/dJMcagYAkjC/08yBfW3I4UVKRIVPszDb01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcuhyX0%2FdJMcagYAkjC%2F08yBfW3I4UVKRIVPszDb01%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;451&quot; height=&quot;163&quot; data-origin-width=&quot;451&quot; data-origin-height=&quot;163&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1422&quot; data-origin-height=&quot;278&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OrNz9/dJMcagYAklR/mgf2xekkhngHFR1s9zofPk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OrNz9/dJMcagYAklR/mgf2xekkhngHFR1s9zofPk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OrNz9/dJMcagYAklR/mgf2xekkhngHFR1s9zofPk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOrNz9%2FdJMcagYAklR%2Fmgf2xekkhngHFR1s9zofPk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1422&quot; height=&quot;278&quot; data-origin-width=&quot;1422&quot; data-origin-height=&quot;278&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 메모리가 폭발하지 않게 되었다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Gemini의 도움&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 이렇게 원인을 해결하는데는 gemini의 도움이 컸다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. camera node는 30fps로 송출&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 터질때의 메모리 사용량이 6GB(swap 포함인듯?)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 터지는데까지 50분 소요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3가지 단서를 주니까 즉시 메모리 누수 문제라는 것을 추론해냈다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;649&quot; data-origin-height=&quot;287&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/soojs/dJMcahQKq70/3oK5Oc0ozAUFKvcxJrysOk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/soojs/dJMcahQKq70/3oK5Oc0ozAUFKvcxJrysOk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/soojs/dJMcahQKq70/3oK5Oc0ozAUFKvcxJrysOk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fsoojs%2FdJMcahQKq70%2F3oK5Oc0ozAUFKvcxJrysOk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;649&quot; height=&quot;287&quot; data-origin-width=&quot;649&quot; data-origin-height=&quot;287&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;진짜 이 답변 보고서는 이게 특이점인가 싶을 정도로 소름이 돋았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정말로 640*480 해상도의 jpeg 이미지를 송출하고 있었기 때문이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 파드가 문제인것까지만 확인했지 어떻게 메모리가 터지는지는 몰랐는데,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Gemini 덕분에 모든 이미지들이 램에 저장되고 있다는걸 깨달을 수 있었다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>라즈베리파이 클러스터/분산처리 프레임워크</category>
      <category>gemini</category>
      <category>라즈베리파이</category>
      <category>메모리 누수</category>
      <category>프레임워크</category>
      <author>seolgugu</author>
      <guid isPermaLink="true">https://seolgu.tistory.com/28</guid>
      <comments>https://seolgu.tistory.com/28#entry28comment</comments>
      <pubDate>Sat, 24 Jan 2026 19:22:44 +0900</pubDate>
    </item>
    <item>
      <title>[ROS2] RVIZ에서 URDF가 안뜨는 문제 해결</title>
      <link>https://seolgu.tistory.com/27</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;ROS2를 로봇에서 실제로 활용해보기 전에, 시뮬레이션으로 먼저 제어에 익숙해진 다음에 실물 로봇으로 넘어가는게 나을 것 같다는 생각에 윈도우 노트북 위에 WSL2를 통해 ROS2를 설치하였다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇게 간단한 URDF를 만들고 걷는 흉내를 내보는 도중, RVIZ에서 로봇 모양이 제대로 안뜨는 문제가 발생했다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 돌리던 코드는 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;background-color: #282c34; color: #bbbbbb;&quot;&gt;
&lt;div&gt;&lt;span style=&quot;color: #5c6370;&quot;&gt;#biped_view.launch.py&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; os&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; launch &lt;/span&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; LaunchDescription&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; launch_ros.actions &lt;/span&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; Node&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;generate_launch_description&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;():&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #5c6370;&quot;&gt;# 1. URDF 파일의 절대 경로 설정 (본인의 환경에 맞게 수정됨)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; urdf_path &lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; os.path.expanduser(&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;'~/humanoid_ws/src/simple_biped.urdf'&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;)&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #5c6370;&quot;&gt;# 2. URDF 파일 내용 읽기&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;with&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #56b6c2;&quot;&gt;open&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;(urdf_path, &lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;'r'&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;as&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; infp:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; robot_desc &lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; infp.read()&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; LaunchDescription([&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #5c6370;&quot;&gt;# 1. Robot State Publisher: 파라미터로 URDF 내용을 전달&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Node(&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;package&lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;'robot_state_publisher'&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;executable&lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;'robot_state_publisher'&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;'robot_state_publisher'&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;output&lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;'screen'&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;parameters&lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;[{&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;'robot_description'&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;: robot_desc}]&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ),&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #5c6370;&quot;&gt;# 2. RViz2: 설정 없이 깨끗하게 실행&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Node(&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;package&lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;'rviz2'&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;executable&lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;'rviz2'&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;'rviz2'&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;output&lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;'screen'&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; ])&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;background-color: #282c34; color: #bbbbbb;&quot;&gt;
&lt;div&gt;&lt;span style=&quot;color: #5c6370;&quot;&gt;#leg_ik_controller.py&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; rclpy&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; rclpy.node &lt;/span&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; Node&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; sensor_msgs.msg &lt;/span&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; JointState&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; math&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #e5c07b;&quot;&gt;LegIKController&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;Node&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;):&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #56b6c2;&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;):&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;super&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color: #56b6c2;&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;'leg_ik_controller'&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;.publisher_ &lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;.create_publisher(JointState, &lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;'joint_states'&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;10&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;.timer &lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;.create_timer(&lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;0.05&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;.timer_callback)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;.counter &lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;0.0&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #5c6370;&quot;&gt;# 다리 길이 (URDF 설정값과 일치해야 함)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;.L1 &lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;0.4&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #5c6370;&quot;&gt;# 허벅지&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;.L2 &lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;0.4&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #5c6370;&quot;&gt;# 종아리&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;solve_ik&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;x&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;z&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;):&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #5c6370;&quot;&gt;# 코사인 법칙을 이용한 역기구학 계산&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; dist_sq &lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; x&lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;**&lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; z&lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;**&lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;2&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cos_theta2 &lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; (dist_sq &lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;.L1&lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;**&lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;.L2&lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;**&lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;.L1 &lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;.L2)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cos_theta2 &lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #56b6c2;&quot;&gt;max&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;1.0&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #56b6c2;&quot;&gt;min&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;1.0&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;, cos_theta2)) &lt;/span&gt;&lt;span style=&quot;color: #5c6370;&quot;&gt;# 수치 에러 방지&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; theta2 &lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; math.acos(cos_theta2)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; theta1 &lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; math.atan2(x, &lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;z) &lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; math.atan2(&lt;/span&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;.L2 &lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; math.sin(theta2), &lt;/span&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;.L1 &lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;.L2 &lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; math.cos(theta2))&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; theta1, theta2&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;timer_callback&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;):&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; msg &lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; JointState()&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; msg.header.stamp &lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;.get_clock().now().to_msg()&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; msg.name &lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;'r_hip_joint'&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;'r_knee_joint'&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;'l_hip_joint'&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;'l_knee_joint'&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;]&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #5c6370;&quot;&gt;# 발바닥이 그릴 궤적 설계 (예: 타원형 궤적)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #5c6370;&quot;&gt;# x: 앞뒤 이동, z: 위아래 이동&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; target_x &lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;0.1&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; math.sin(&lt;/span&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;.counter) &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; target_z &lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;0.6&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;0.05&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; math.cos(&lt;/span&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;.counter) &lt;/span&gt;&lt;span style=&quot;color: #5c6370;&quot;&gt;# 기본 -0.6m 높이에서 까딱거림&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; r_theta1, r_theta2 &lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;.solve_ik(target_x, target_z)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #5c6370;&quot;&gt;# 왼쪽 다리는 반대 위상으로 (걷는 동작 모사)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; l_theta1, l_theta2 &lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;.solve_ik(&lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;target_x, target_z)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; msg.position &lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; [r_theta1, r_theta2, l_theta1, l_theta2]&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;.publisher_.publish(msg)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;.counter &lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;0.1&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;main&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;args&lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;None&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;):&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; rclpy.init(&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;args&lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;args)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; node &lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; LegIKController()&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; rclpy.spin(node)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; node.destroy_node()&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; rclpy.shutdown()&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #c678dd;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; __name__ &lt;/span&gt;&lt;span style=&quot;color: #61afef;&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;'__main__'&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; main()&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;background-color: #282c34; color: #bbbbbb;&quot;&gt;
&lt;div&gt;&lt;span style=&quot;color: #5c6370;&quot;&gt;&amp;lt;!-- simple_biped.urdf --&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;lt;?&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;xml&lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt; version&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;1.0&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;robot&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;simple_biped&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;material&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;blue&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;color&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;rgba&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;0 0 0.8 1&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;material&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;material&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;white&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;color&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;rgba&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;1 1 1 1&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;material&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #5c6370;&quot;&gt;&amp;lt;!-- Base --&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;link&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;base_link&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;visual&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;geometry&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;box&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;size&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;0.2 0.3 0.1&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;geometry&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;material&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;blue&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;visual&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;link&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #5c6370;&quot;&gt;&amp;lt;!-- Right leg --&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;link&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;r_thigh&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;visual&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;origin&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;xyz&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;0 0 -0.2&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;rpy&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;0 0 0&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;geometry&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;cylinder&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;0.4&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;radius&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;0.04&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;geometry&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;material&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;white&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;visual&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;link&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;joint&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;r_hip_joint&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;revolute&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;parent&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;link&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;base_link&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;child&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;link&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;r_thigh&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;origin&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;xyz&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;0 -0.1 0&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;rpy&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;0 0 0&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;axis&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;xyz&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;0 1 0&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;limit&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;effort&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;30&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;lower&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;-1.57&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;upper&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;1.57&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;velocity&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;1.0&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;joint&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;link&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;r_shin&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;visual&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;origin&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;xyz&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;0 0 -0.2&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;rpy&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;0 0 0&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;geometry&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;cylinder&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;0.4&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;radius&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;0.04&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;geometry&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;material&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;blue&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;visual&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;link&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;joint&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;r_knee_joint&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;revolute&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;parent&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;link&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;r_thigh&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;child&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;link&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;r_shin&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;origin&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;xyz&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;0 0 -0.4&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;rpy&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;0 0 0&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;axis&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;xyz&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;0 1 0&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;limit&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;effort&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;30&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;lower&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;0&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;upper&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;2.6&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;velocity&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;1.0&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;joint&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #5c6370;&quot;&gt;&amp;lt;!-- Left leg --&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;link&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;l_thigh&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;visual&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;origin&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;xyz&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;0 0 -0.2&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;rpy&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;0 0 0&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;geometry&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;cylinder&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;0.4&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;radius&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;0.04&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;geometry&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;material&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;white&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;visual&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;link&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;joint&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;l_hip_joint&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;revolute&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;parent&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;link&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;base_link&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;child&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;link&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;l_thigh&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;origin&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;xyz&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;0 0.1 0&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;rpy&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;0 0 0&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;axis&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;xyz&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;0 1 0&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;limit&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;effort&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;30&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;lower&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;-1.57&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;upper&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;1.57&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;velocity&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;1.0&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;joint&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;link&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;l_shin&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;visual&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;origin&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;xyz&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;0 0 -0.2&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;rpy&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;0 0 0&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;geometry&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;cylinder&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;0.4&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;radius&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;0.04&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;geometry&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;material&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;blue&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;visual&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;link&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;joint&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;l_knee_joint&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;revolute&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;parent&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;link&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;l_thigh&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;child&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;link&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;l_shin&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;origin&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;xyz&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;0 0 -0.4&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;rpy&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;0 0 0&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;axis&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;xyz&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;0 1 0&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;limit&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;effort&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;30&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;lower&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;0&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;upper&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;2.6&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d19a66;&quot;&gt;velocity&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #98c379;&quot;&gt;&quot;1.0&quot;&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;joint&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #e06c75;&quot;&gt;robot&lt;/span&gt;&lt;span style=&quot;color: #bbbbbb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단히 허벅지와 종아리로 이루어진 로봇이다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1768740344522&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;~/humanoid_ws/src$ ros2 launch biped_view.launch.py&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이걸 위 명령으로 실행시키고,&lt;/p&gt;
&lt;pre id=&quot;code_1768740403246&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;~/humanoid_ws/src$ python3 leg_ik_controller.py&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 터미널에서 위 명령으로 publisher를 생성해주면 rviz 창이 뜰텐데, 몇가지 설정만 해주면 된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;353&quot; data-origin-height=&quot;171&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DeGVQ/dJMcajuaGkA/fSDOqr6kvkNzmTvQ9YLyE0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DeGVQ/dJMcajuaGkA/fSDOqr6kvkNzmTvQ9YLyE0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DeGVQ/dJMcajuaGkA/fSDOqr6kvkNzmTvQ9YLyE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDeGVQ%2FdJMcajuaGkA%2FfSDOqr6kvkNzmTvQ9YLyE0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;353&quot; height=&quot;171&quot; data-origin-width=&quot;353&quot; data-origin-height=&quot;171&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 화면에서, Global Options &amp;gt; Fixed Frame 부분 우측에 map이라고 쓰인 부분을 클릭해서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사진처럼 base_link로 설정해줘야한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;862&quot; data-origin-height=&quot;694&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8AYU5/dJMcagEh60B/kMHjMNVb1hfUH2eVmRzAO0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8AYU5/dJMcagEh60B/kMHjMNVb1hfUH2eVmRzAO0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8AYU5/dJMcagEh60B/kMHjMNVb1hfUH2eVmRzAO0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8AYU5%2FdJMcagEh60B%2FkMHjMNVb1hfUH2eVmRzAO0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;597&quot; height=&quot;481&quot; data-origin-width=&quot;862&quot; data-origin-height=&quot;694&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 왼쪽 하단의 Add를 누르고 뜨는 화면에서 RobotModel을 추가해주고,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시 Add를 눌러서 TF도 추가해주면 아래처럼 로봇같이 생긴 무언가가 움직이는걸 볼 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1209&quot; data-origin-height=&quot;693&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cg2mYX/dJMcafFmwch/aKQMdJskK4xHpkcRgc2OyK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cg2mYX/dJMcafFmwch/aKQMdJskK4xHpkcRgc2OyK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cg2mYX/dJMcafFmwch/aKQMdJskK4xHpkcRgc2OyK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcg2mYX%2FdJMcafFmwch%2FaKQMdJskK4xHpkcRgc2OyK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1209&quot; height=&quot;693&quot; data-origin-width=&quot;1209&quot; data-origin-height=&quot;693&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;난 이게 문제 없는 화면인줄 알았는데, 자세히 보니 종아리가 없다는 것에서 뭔가 잘못된걸 느꼈다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;342&quot; data-origin-height=&quot;318&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qfDKo/dJMcadgrevv/mnu6PP0eIgKKkI2SGXDcV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qfDKo/dJMcadgrevv/mnu6PP0eIgKKkI2SGXDcV0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qfDKo/dJMcadgrevv/mnu6PP0eIgKKkI2SGXDcV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqfDKo%2FdJMcadgrevv%2Fmnu6PP0eIgKKkI2SGXDcV0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;342&quot; height=&quot;318&quot; data-origin-width=&quot;342&quot; data-origin-height=&quot;318&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;분명 여기 Status도 Ok로 떠있는데, 이 상태는 urdf가 제대로 불러와진 상태가 아니고,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Description Topic을 지정해줘야 하는 상태였다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;342&quot; data-origin-height=&quot;318&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUxFOb/dJMb99ZrYuv/JrD95K486x6Vje8sJhzcCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUxFOb/dJMb99ZrYuv/JrD95K486x6Vje8sJhzcCK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUxFOb/dJMb99ZrYuv/JrD95K486x6Vje8sJhzcCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUxFOb%2FdJMb99ZrYuv%2FJrD95K486x6Vje8sJhzcCK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;342&quot; height=&quot;318&quot; data-origin-width=&quot;342&quot; data-origin-height=&quot;318&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 Description Topic 옆의 빈칸을 눌러주니, Topic을 지정해줄 수 있었다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1208&quot; data-origin-height=&quot;691&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UoPVq/dJMcagEh62U/bqMwgJLSjWhAJKAUEfJxtk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UoPVq/dJMcagEh62U/bqMwgJLSjWhAJKAUEfJxtk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UoPVq/dJMcagEh62U/bqMwgJLSjWhAJKAUEfJxtk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUoPVq%2FdJMcagEh62U%2FbqMwgJLSjWhAJKAUEfJxtk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1208&quot; height=&quot;691&quot; data-origin-width=&quot;1208&quot; data-origin-height=&quot;691&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Topic 하나를 지정해주니 문제없이 허벅지와 종아리가 뜨는걸 확인할 수 있었다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 보던 허벅지인줄 알던 노란색 막대기는,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;부모 좌표계에서 자식 좌표계로 가는 변위를 그려주는 Arrow 기능이었던 거였다.&lt;/p&gt;</description>
      <category>ROS2</category>
      <category>ROS2</category>
      <category>Rviz</category>
      <category>Topic</category>
      <category>URDF</category>
      <category>wsl2</category>
      <author>seolgugu</author>
      <guid isPermaLink="true">https://seolgu.tistory.com/27</guid>
      <comments>https://seolgu.tistory.com/27#entry27comment</comments>
      <pubDate>Sun, 18 Jan 2026 22:01:42 +0900</pubDate>
    </item>
    <item>
      <title>[ROS2] 터틀봇3 에러 : There is no status packet!</title>
      <link>https://seolgu.tistory.com/26</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 현상&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://emanual.robotis.com/docs/en/platform/turtlebot3/manipulation/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://emanual.robotis.com/docs/en/platform/turtlebot3/manipulation/ &lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1767427913826&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;ROBOTIS e-Manual&quot; data-og-description=&quot;&quot; data-og-host=&quot;emanual.robotis.com&quot; data-og-source-url=&quot;https://emanual.robotis.com/docs/en/platform/turtlebot3/manipulation/&quot; data-og-url=&quot;https://emanual.robotis.com/docs/en/platform/turtlebot3/manipulation/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/WkVIV/hyZQWCq1Bt/leJvBMHJwXX7NW8Pe9wpU0/img.png?width=1342&amp;amp;height=752&amp;amp;face=0_0_1342_752,https://scrap.kakaocdn.net/dn/klFVB/hyZQQvrUGl/XpqysdMZBGNKdT65RPsaA1/img.png?width=1342&amp;amp;height=752&amp;amp;face=0_0_1342_752,https://scrap.kakaocdn.net/dn/bwi0V4/hyZRaOLUV2/KClKi4bcXpwRg23kubd6t0/img.png?width=740&amp;amp;height=550&amp;amp;face=0_0_740_550&quot;&gt;&lt;a href=&quot;https://emanual.robotis.com/docs/en/platform/turtlebot3/manipulation/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://emanual.robotis.com/docs/en/platform/turtlebot3/manipulation/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/WkVIV/hyZQWCq1Bt/leJvBMHJwXX7NW8Pe9wpU0/img.png?width=1342&amp;amp;height=752&amp;amp;face=0_0_1342_752,https://scrap.kakaocdn.net/dn/klFVB/hyZQQvrUGl/XpqysdMZBGNKdT65RPsaA1/img.png?width=1342&amp;amp;height=752&amp;amp;face=0_0_1342_752,https://scrap.kakaocdn.net/dn/bwi0V4/hyZRaOLUV2/KClKi4bcXpwRg23kubd6t0/img.png?width=740&amp;amp;height=550&amp;amp;face=0_0_740_550');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;ROBOTIS e-Manual&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;emanual.robotis.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 매뉴얼의 7.7 부분을 수행하던 중, 터틀봇3에서 아래 명령을 실행하면&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;mel&quot; style=&quot;background-color: #000000; color: #ffffff; text-align: start;&quot;&gt;&lt;code&gt;  $ ros2 launch turtlebot3_manipulation_bringup hardware.launch.py&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같은 문구를 뱉으며 프로세스가 죽어버리는 현상이 발생했다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;주요 로그:&amp;nbsp;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[ros2_control_node-1]&amp;nbsp;[ERROR]&amp;nbsp;[DynamixelSDKWrapper]&amp;nbsp;[TxRxResult]&amp;nbsp;There&amp;nbsp;is&amp;nbsp;no&amp;nbsp;status&amp;nbsp;packet!&lt;br /&gt;[ros2_control_node-1]&amp;nbsp;***&amp;nbsp;stack&amp;nbsp;smashing&amp;nbsp;detected&amp;nbsp;***:&amp;nbsp;terminated&lt;br /&gt;[ros2_control_node-1]&amp;nbsp;#7&amp;nbsp;Object&amp;nbsp;&quot;libturtlebot3_manipulation_hardware.so&quot;,&amp;nbsp;at&amp;nbsp;...,&amp;nbsp;in&amp;nbsp;DynamixelSDKWrapper::write(...)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 원인&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에는 OpenCR의 펌웨어와, ros2 humble간의 패킷 사이즈가 버전 차이 이슈로 맞지 않나 싶어서 아두이노IDE로 OpenCR의 펌웨어를 다시 올려보기도 했고, ros2 패키지를 처음부터 다시 빌드하기도 했었으나,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/ROBOTIS-GIT/turtlebot3_manipulation/issues/63&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/ROBOTIS-GIT/turtlebot3_manipulation/issues/63&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1767428988412&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;Open Manipulator Fails BringUP &amp;middot; Issue #63 &amp;middot; ROBOTIS-GIT/turtlebot3_manipulation&quot; data-og-description=&quot;Hi everyone, I'm having this errors (exception) when trying to bringup the turtlebot3 with the open manipulator: $ ros2 launch turtlebot3_manipulation_bringup hardware.launch.py [INFO] [launch]: Al...&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/ROBOTIS-GIT/turtlebot3_manipulation/issues/63&quot; data-og-url=&quot;https://github.com/ROBOTIS-GIT/turtlebot3_manipulation/issues/63&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/c4r5JC/hyZRcsgvq7/HFKpSF07pLMJ7xZRibtwZK/img.png?width=1200&amp;amp;height=600&amp;amp;face=982_114_1051_189,https://scrap.kakaocdn.net/dn/gx8tb/hyZPHmAdep/W01w1ulHppGFAmlHnAGIUK/img.png?width=1200&amp;amp;height=600&amp;amp;face=982_114_1051_189&quot;&gt;&lt;a href=&quot;https://github.com/ROBOTIS-GIT/turtlebot3_manipulation/issues/63&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/ROBOTIS-GIT/turtlebot3_manipulation/issues/63&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/c4r5JC/hyZRcsgvq7/HFKpSF07pLMJ7xZRibtwZK/img.png?width=1200&amp;amp;height=600&amp;amp;face=982_114_1051_189,https://scrap.kakaocdn.net/dn/gx8tb/hyZPHmAdep/W01w1ulHppGFAmlHnAGIUK/img.png?width=1200&amp;amp;height=600&amp;amp;face=982_114_1051_189');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Open Manipulator Fails BringUP &amp;middot; Issue #63 &amp;middot; ROBOTIS-GIT/turtlebot3_manipulation&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Hi everyone, I'm having this errors (exception) when trying to bringup the turtlebot3 with the open manipulator: $ ros2 launch turtlebot3_manipulation_bringup hardware.launch.py [INFO] [launch]: Al...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 깃허브 이슈를 통해 진짜 원인은 다이나믹셀 내부 설정인 Return Delay Time이 기본값(500)으로 설정되어있었기 때문이라는걸 알 수 있었다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ros2 humble의 ros2_control의 데이터 i/o 속도보다 모터가 응답을 늦게 주는 바람에 패킷들이 서로 뒤섞이는 문제가 발생하게 된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 정해진 메모리 범위를 넘어서 기록하게 되어 강제종료되었기 때문에 stack smashing detected 같은 메시지가 뜬 것이었다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 해결 과정&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Step 1: OpenCR 펌웨어 변경&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OpenCR을 U2D2와 같은 통신 통로로 쓰기 위해, 펌웨어를 변경해야한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1.&lt;/b&gt; 라즈베리파이와 연결되어있는 케이블을 OpenCR에서 제거하고, 컴퓨터와 연결된 USB 케이블을 OpenCR과 연결한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2.&lt;/b&gt; 아두이노 IDE에서 파일 &amp;gt; 예제 &amp;gt; OpenCR &amp;gt; 10.Etc &amp;gt; usb_to_dxl 파일을 불러와 OpenCR에 업로드한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Step 2: 다이나믹셀 위자드 설정 변경&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1.&lt;/b&gt; Dynamixel Wizard 2.0 프로그램에서 &lt;b&gt;검색&lt;/b&gt; 버튼을 통해 연결된 모든 모터들을 연결한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2.&lt;/b&gt; 연결된 모든 모터를 클릭해 9 번 부근의 &lt;b&gt;Return Delay Time&lt;/b&gt; 옵션을 0으로 변경한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(본인은 250으로 되어있길래 0으로 변경)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(변경하고 아래쪽 저장버튼 눌러야함)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Step 3: OpenCR 펌웨어 복구&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1.&lt;/b&gt; 아두이노 IDE에서 OpenCR의 펌웨어를 기존의 펌웨어로 다시 업로드한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;해결&lt;/h3&gt;
&lt;pre class=&quot;mel&quot; style=&quot;background-color: #000000; color: #ffffff; text-align: start;&quot;&gt;&lt;code&gt;  $ ros2 launch turtlebot3_manipulation_bringup hardware.launch.py&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이후 다시 위 명령을 실행하니 아주 깔끔히 실행이 잘 되는걸 확인할 수 있었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1180&quot; data-origin-height=&quot;563&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cCFEfm/dJMcafSN5PE/GRCUZqezbO8YLYltf9YL9k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cCFEfm/dJMcafSN5PE/GRCUZqezbO8YLYltf9YL9k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cCFEfm/dJMcafSN5PE/GRCUZqezbO8YLYltf9YL9k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcCFEfm%2FdJMcafSN5PE%2FGRCUZqezbO8YLYltf9YL9k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1180&quot; height=&quot;563&quot; data-origin-width=&quot;1180&quot; data-origin-height=&quot;563&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>ROS2</category>
      <category>ROS2</category>
      <category>다이나믹셀</category>
      <category>매니퓰레이터</category>
      <category>오류</category>
      <category>터틀봇3</category>
      <author>seolgugu</author>
      <guid isPermaLink="true">https://seolgu.tistory.com/26</guid>
      <comments>https://seolgu.tistory.com/26#entry26comment</comments>
      <pubDate>Sat, 3 Jan 2026 17:33:50 +0900</pubDate>
    </item>
    <item>
      <title>[ROS2] WSL2 네트워크 미러링 설정으로 원격 환경 구축하기</title>
      <link>https://seolgu.tistory.com/25</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://emanual.robotis.com/docs/en/platform/turtlebot3/sbc_setup/#sbc-setup&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://emanual.robotis.com/docs/en/platform/turtlebot3/sbc_setup/#sbc-setup&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1766925862290&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;ROBOTIS e-Manual&quot; data-og-description=&quot;&quot; data-og-host=&quot;emanual.robotis.com&quot; data-og-source-url=&quot;https://emanual.robotis.com/docs/en/platform/turtlebot3/sbc_setup/#sbc-setup&quot; data-og-url=&quot;https://emanual.robotis.com/docs/en/platform/turtlebot3/sbc_setup/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/pHZWk/hyZQByXdYJ/6WRGFAbioknWi6UqVT6ht0/img.png?width=600&amp;amp;height=581&amp;amp;face=0_0_600_581,https://scrap.kakaocdn.net/dn/4Dg3j/hyZQwj9bKV/26EkfFdkdNrIazmPxKUJv1/img.png?width=399&amp;amp;height=484&amp;amp;face=0_0_399_484,https://scrap.kakaocdn.net/dn/G3YHv/hyZQEWN4IT/crKh6xEHj2kakgBKLXAK8K/img.png?width=397&amp;amp;height=483&amp;amp;face=0_0_397_483&quot;&gt;&lt;a href=&quot;https://emanual.robotis.com/docs/en/platform/turtlebot3/sbc_setup/#sbc-setup&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://emanual.robotis.com/docs/en/platform/turtlebot3/sbc_setup/#sbc-setup&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/pHZWk/hyZQByXdYJ/6WRGFAbioknWi6UqVT6ht0/img.png?width=600&amp;amp;height=581&amp;amp;face=0_0_600_581,https://scrap.kakaocdn.net/dn/4Dg3j/hyZQwj9bKV/26EkfFdkdNrIazmPxKUJv1/img.png?width=399&amp;amp;height=484&amp;amp;face=0_0_399_484,https://scrap.kakaocdn.net/dn/G3YHv/hyZQEWN4IT/crKh6xEHj2kakgBKLXAK8K/img.png?width=397&amp;amp;height=483&amp;amp;face=0_0_397_483');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;ROBOTIS e-Manual&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;emanual.robotis.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;터틀봇3의 e-manual을 보고 라즈베리파이를 세팅하고 있었는데,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;mel&quot; style=&quot;background-color: #000000; color: #ffffff; text-align: start;&quot;&gt;&lt;code&gt;$ ros2 launch turtlebot3_bringup camera.launch.py&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라이브러리를 다 설치하고 노드를 실행하는 이 부분에서부터 문제가 생겼다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;elixir&quot; style=&quot;background-color: #000000; color: #ffffff; text-align: start;&quot;&gt;&lt;code&gt;$ rqt_image_view&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원격 pc (WSL2)에서 카메라 영상을 보여주는 위 명령을 실행하면&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같은 빈 화면만 뜨고, 좌측 상단의 topic도 아무것도 뜨지 않았다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-12-28 200946.png&quot; data-origin-width=&quot;853&quot; data-origin-height=&quot;945&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/biHzDN/dJMcagRFnF4/e8HxmM1AI3j2UoTtYybqF1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/biHzDN/dJMcagRFnF4/e8HxmM1AI3j2UoTtYybqF1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/biHzDN/dJMcagRFnF4/e8HxmM1AI3j2UoTtYybqF1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbiHzDN%2FdJMcagRFnF4%2Fe8HxmM1AI3j2UoTtYybqF1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;556&quot; height=&quot;616&quot; data-filename=&quot;스크린샷 2025-12-28 200946.png&quot; data-origin-width=&quot;853&quot; data-origin-height=&quot;945&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1766926198080&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;~$ ros2 topic list
/parameter_events
/rosout&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;topic들을 조회하면 /parameter/events, /rosout만 뜨는 상황이었고 domain_id나 이외 설정들은 문제가 없는 상태였기에 네트워크에 문제가 있다는걸 알 수 있었다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;원인&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;네이티브 리눅스와는 다르게, WSL2에서는 네트워크가 윈도우 내부의 가상 네트워크 뒤에 숨어있는 상태이기 때문에 터틀봇이 보내는 멀티캐스트 데이터가 WSL2 안으로 제대로 들어오지 못하는 것이 원인이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;해결방법&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. WSL2 미러링모드 설정&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;윈도우 11에서 지원하는 미러링 모드를 쓰면, WSL2가 윈도우의 IP를 그대로 공유해서 쓴다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 터틀봇과 같은 와이파이 대역에 바로 접속할 수 있게 된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;미러링 모드 설정 없이 WSL2 내부에서 ip를 확인해본다면 172.~으로 시작하는 ip가 나오게 되는데,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;미러링모드를 설정한 후에는 WSL2가 돌아가고 있는 PC와 동일한 IP주소를 가지게 된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설정하기 위해서는 &lt;b&gt;C:\Users\사용자명&lt;/b&gt; 폴더에 파일을 하나 만들어 아래 내용을 그대로 붙여넣어주면 된다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1766926848640&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[wsl2]
networkingMode=mirrored
firewall=true&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;84&quot; data-origin-height=&quot;103&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bYux1r/dJMcabQmm4l/710poAfIkkb3OvdsYVgNak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bYux1r/dJMcabQmm4l/710poAfIkkb3OvdsYVgNak/img.png&quot; data-alt=&quot;.wslconfig 파일&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bYux1r/dJMcabQmm4l/710poAfIkkb3OvdsYVgNak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbYux1r%2FdJMcabQmm4l%2F710poAfIkkb3OvdsYVgNak%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;84&quot; height=&quot;103&quot; data-origin-width=&quot;84&quot; data-origin-height=&quot;103&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;.wslconfig 파일&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파일을 생성했다면 &lt;b&gt;wsl --shutdown&lt;/b&gt; 명령으로 wsl을 재부팅하면, WSL2 에서의 IP가 호스트 PC의 주소와 같게 바뀐 것을 확인할 수 있다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 양쪽 기기를 한번씩 재부팅 한 후에 노드를 다시 실행시키고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;rqt 창 왼쪽 상단에서 /camera/image_raw/compressed 를 선택하면&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;861&quot; data-origin-height=&quot;176&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cV9BrY/dJMcaaDU6Ik/xuMJl301YpsZRApEZZg1S0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cV9BrY/dJMcaaDU6Ik/xuMJl301YpsZRApEZZg1S0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cV9BrY/dJMcaaDU6Ik/xuMJl301YpsZRApEZZg1S0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcV9BrY%2FdJMcaaDU6Ik%2FxuMJl301YpsZRApEZZg1S0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;861&quot; height=&quot;176&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;861&quot; data-origin-height=&quot;176&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;898&quot; data-origin-height=&quot;472&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7PFwo/dJMcajngUPQ/N4Of9ByKTkzXKNf7jigP4k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7PFwo/dJMcajngUPQ/N4Of9ByKTkzXKNf7jigP4k/img.png&quot; data-alt=&quot;터틀봇 터미널 로그&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7PFwo/dJMcajngUPQ/N4Of9ByKTkzXKNf7jigP4k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7PFwo%2FdJMcajngUPQ%2FN4Of9ByKTkzXKNf7jigP4k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;608&quot; height=&quot;320&quot; data-origin-width=&quot;898&quot; data-origin-height=&quot;472&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;터틀봇 터미널 로그&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1145&quot; data-origin-height=&quot;504&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NERTy/dJMcahbYeCu/n5ah7EZDrBZJWDFproa15K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NERTy/dJMcahbYeCu/n5ah7EZDrBZJWDFproa15K/img.png&quot; data-alt=&quot;원격 pc 터미널 로그&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NERTy/dJMcahbYeCu/n5ah7EZDrBZJWDFproa15K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNERTy%2FdJMcahbYeCu%2Fn5ah7EZDrBZJWDFproa15K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;646&quot; height=&quot;284&quot; data-origin-width=&quot;1145&quot; data-origin-height=&quot;504&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;원격 pc 터미널 로그&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;터미널에서 Unrecognized image encoding [nv21] 과 같은 에러를 뱉는걸 볼 수가 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;카메라는 기본적으로 &lt;b data-index-in-node=&quot;46&quot; data-path-to-node=&quot;14&quot;&gt;NV21&lt;/b&gt;이나 압축된 포맷으로 데이터를 쏘려고 시도한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 현재 ROS 2 버전이나 이미지 처리 노드(OpenCV 등)에서는 &lt;b data-index-in-node=&quot;119&quot; data-path-to-node=&quot;14&quot;&gt;RGB888&lt;/b&gt; 같은 표준 포맷을 기대하기 때문에 충돌이 일어나는 것이다. (e-manual 따라하는데 왜 이런 일이 발생하는지는 모르겠다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇기에 아래 명령으로 launch하지 않고 노드를 직접 실행하면서 포맷 파라미터를 지정해버리면&lt;/p&gt;
&lt;pre id=&quot;code_1766929848588&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ros2 run camera_ros camera_node --ros-args -p format:=&quot;RGB888&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 영상이 잘 나오는걸 확인할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;986&quot; data-origin-height=&quot;730&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b235eO/dJMcagRFoBD/3oWbDVs9UYGXulYjMyEgHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b235eO/dJMcagRFoBD/3oWbDVs9UYGXulYjMyEgHk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b235eO/dJMcagRFoBD/3oWbDVs9UYGXulYjMyEgHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb235eO%2FdJMcagRFoBD%2F3oWbDVs9UYGXulYjMyEgHk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;670&quot; height=&quot;496&quot; data-origin-width=&quot;986&quot; data-origin-height=&quot;730&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>ROS2</category>
      <category>ROS2</category>
      <category>turtlebot3</category>
      <category>wsl2</category>
      <category>와플파이</category>
      <category>터틀봇</category>
      <category>터틀봇3</category>
      <author>seolgugu</author>
      <guid isPermaLink="true">https://seolgu.tistory.com/25</guid>
      <comments>https://seolgu.tistory.com/25#entry25comment</comments>
      <pubDate>Sun, 28 Dec 2025 23:02:10 +0900</pubDate>
    </item>
    <item>
      <title>라즈베리파이 클러스터 영상 데이터 분산 처리 (5) 최종 마무리</title>
      <link>https://seolgu.tistory.com/24</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;프로젝트 개요&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라즈베리파이 클러스터에서 실시간 영상 데이터를 노드별로 분산 처리하면 처리량을 향상시킬 수 있는지를 검증하기 위해 진행한 프로젝트다. 수평확장성을 위해 마이크로 서비스 아키텍처로 설계했고, 각 노드는 독립적으로 프레임을 소비/처리하는 구조를 적용했다.&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;기술 스택&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;FastAPI, Redis, YOLO, K3S&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;최종 결과물&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;723&quot; data-origin-height=&quot;600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lcVaF/dJMb995YUOo/XvP0HOxzSc0AcsN1eRRTZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lcVaF/dJMb995YUOo/XvP0HOxzSc0AcsN1eRRTZK/img.png&quot; data-alt=&quot;웹에 배포된 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lcVaF/dJMb995YUOo/XvP0HOxzSc0AcsN1eRRTZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlcVaF%2FdJMb995YUOo%2FXvP0HOxzSc0AcsN1eRRTZK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;550&quot; height=&quot;456&quot; data-origin-width=&quot;723&quot; data-origin-height=&quot;600&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;웹에 배포된 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;945&quot; data-origin-height=&quot;156&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxRYaM/dJMcahiDlZG/asmQ9jdWbLbmORQYyYbAEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxRYaM/dJMcahiDlZG/asmQ9jdWbLbmORQYyYbAEK/img.png&quot; data-alt=&quot;배포된 파드들&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxRYaM/dJMcahiDlZG/asmQ9jdWbLbmORQYyYbAEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxRYaM%2FdJMcahiDlZG%2FasmQ9jdWbLbmORQYyYbAEK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;945&quot; height=&quot;156&quot; data-origin-width=&quot;945&quot; data-origin-height=&quot;156&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;배포된 파드들&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;초기에는 라즈베리파이만으로 구성했지만, 마스터노드를 N100기반 미니pc로 교체하면서 파드 3개에서 안정적으로 consumer를 실행할 수 있었다. 이를 통해 전체 처리 성능이 약 16fps까지 증가했고, 노드 수 증가에 따라 5 -&amp;gt; 10 -&amp;gt; 16fps형태의 선형적 처리량 향상을 확인했다.&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2417&quot; data-origin-height=&quot;2118&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cKfTiF/dJMcabW1n0G/kWIKKLhNod8PKkv2qUVjGk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cKfTiF/dJMcabW1n0G/kWIKKLhNod8PKkv2qUVjGk/img.png&quot; data-alt=&quot;카메라가 장착된 라즈베리파이 클러스터&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cKfTiF/dJMcabW1n0G/kWIKKLhNod8PKkv2qUVjGk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcKfTiF%2FdJMcabW1n0G%2FkWIKKLhNod8PKkv2qUVjGk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2417&quot; height=&quot;2118&quot; data-origin-width=&quot;2417&quot; data-origin-height=&quot;2118&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;카메라가 장착된 라즈베리파이 클러스터&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;마이크로 서비스 구조&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;551&quot; data-origin-height=&quot;991&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/y9xwR/dJMcajgoQQA/zfRINOWlCMSWiPcBWbDdAk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/y9xwR/dJMcajgoQQA/zfRINOWlCMSWiPcBWbDdAk/img.jpg&quot; data-alt=&quot;최종적으로 완성된 아키텍처&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/y9xwR/dJMcajgoQQA/zfRINOWlCMSWiPcBWbDdAk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fy9xwR%2FdJMcajgoQQA%2FzfRINOWlCMSWiPcBWbDdAk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;551&quot; height=&quot;991&quot; data-origin-width=&quot;551&quot; data-origin-height=&quot;991&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;최종적으로 완성된 아키텍처&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 구조는 '최신 프레임만 소비하고, 오래된 프레임은 즉시 폐기하는 방식'을 통해 지연 누적 문제를 완전히 제거하고, 노드 수당 성능이 거의 선형적으로 증가하는 형태를 만들었다.&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;소회&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트 초기에는 메시지큐 기반으로 프레임을 배포할 계획이었다. 심지어 프레임을 NFS에 저장한 뒤 메타데이터만 메시지큐로 전달하는 방식, 메시지큐와 Redis를 혼용하는 방식 등 다양한 구조를 시도했다. 요소들을 이해하고 있음에도, 메시지큐를 써야한다는 전제에서 출발하다 보니 구조가 계속 복잡해지고 스스로도 방향성을 잃게 됐다.&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;문제를 해결하기 위해 기술을 선택하는 것이 아니라, 이미 선택한 기술을 사용하기 위해 문제를 맞추려 했던 것이 가장 큰 원인이었다. 분산처리를 실험해보겠다는 초기 목적은 사라지고, 어느 시점부터는 메시지큐를 사용하는 것 자체가 목표로 변해 있었다.&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;하지만 필요성을 하나씩 다시 질문하다보니, 오히려 메시지큐가 필요 없다는 결론에 도달했다.&amp;nbsp;&lt;br /&gt;결국 가장 중요한 것은 실시간 처리, 그리고 프레임 누적 방지 였다. 최신 프레임만을 가져가고, 지나간 프레임은 버려도 무방한 구조라는 점을 다시 정의했을 때 Redis 하나로도 전체 파이프라인이 훨씬 단순하고 효과적으로 동작했다.&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;향후계획&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 프로젝트를 통해 저성능 엣지 디바이스에서도 마이크로서비스를 이용한 수평 확장이 충분히 가능하다는 점을 검증했다. 하지만 현재 구조에서는 여전히 한 프레임을 처리하는 데 약 0.2초가 소요되며, 이는 어떤 방식의 수평 확장으로도 줄일 수 없는 지연이다. 이 지연을 개선하려면 모델 자체를 최적화하거나 경량화하는 방향이 필요하다.&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;따라서 다음 목표는 아래와 같다.&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;1. 모델 경량화 및 성능 개선 실험&lt;br /&gt;- YOLO 계열 모델을 기준으로 모델 경량화를 경험해볼 예정이다.&amp;nbsp;&lt;br /&gt;2. 프레임 단위 분산처리 파이프라인을 경량 프레임워크로 발전&lt;br /&gt;- 쿠버네티스 기반 엣지 분산 영상처리 파이프라인을 단순화해 쉽게 재사용 가능한 소형 프레임워크 형태로 배포해보고 싶다.&amp;nbsp;&lt;br /&gt;3. ROS2 + 쿠버네티스 실험&lt;br /&gt;- ROS2의 컴포넌트 간 통신 구조가 마이크로 서비스와 매우 유사하다는 점에서, 로봇 시스템과 쿠버네티스 클러스터를 접목시키는 새로운 프로젝트를 시도해볼 계획이다.&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>라즈베리파이 클러스터/영상데이터 분산처리</category>
      <category>AI</category>
      <category>k3s</category>
      <category>k8s</category>
      <category>rabbitmq</category>
      <category>redis</category>
      <category>라즈베리파이</category>
      <category>분산처리</category>
      <category>엣지컴퓨팅</category>
      <category>클러스터</category>
      <category>파이프라인</category>
      <author>seolgugu</author>
      <guid isPermaLink="true">https://seolgu.tistory.com/24</guid>
      <comments>https://seolgu.tistory.com/24#entry24comment</comments>
      <pubDate>Thu, 11 Dec 2025 00:21:01 +0900</pubDate>
    </item>
    <item>
      <title>라즈베리파이 클러스터를 활용한 영상데이터 분산처리 (4) YOLO 적용</title>
      <link>https://seolgu.tistory.com/23</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;지난 글에서는 실제 모델이 아닌 time.sleep을 이용해 흐름을 구현했었다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에는 라즈베리파이에 실제 AI모델인 YOLOv5를 탑재해&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 사진처럼 웹페이지에 실시간 영상처리 결과를 확인할 수 있도록 만들었다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;806&quot; data-origin-height=&quot;669&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PYENp/dJMcacOXnRB/5jCt8QPO7UhlVchgQkGGs1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PYENp/dJMcacOXnRB/5jCt8QPO7UhlVchgQkGGs1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PYENp/dJMcacOXnRB/5jCt8QPO7UhlVchgQkGGs1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPYENp%2FdJMcacOXnRB%2F5jCt8QPO7UhlVchgQkGGs1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;502&quot; height=&quot;417&quot; data-origin-width=&quot;806&quot; data-origin-height=&quot;669&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;836&quot; data-origin-height=&quot;677&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/w4fMf/dJMcaaDByqL/2YDmmMm5WOBEVOfaxTTE3k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/w4fMf/dJMcaaDByqL/2YDmmMm5WOBEVOfaxTTE3k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/w4fMf/dJMcaaDByqL/2YDmmMm5WOBEVOfaxTTE3k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fw4fMf%2FdJMcaaDByqL%2F2YDmmMm5WOBEVOfaxTTE3k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;566&quot; height=&quot;458&quot; data-origin-width=&quot;836&quot; data-origin-height=&quot;677&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이와 같이 time.sleep이 있던 부분을 YOLOv5의 처리를 거치도록 간단히 변경해주었고,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로컬에서 예제 파일을 돌려본 후에 필요했던 라이브러리 파일들을 Dockerfile에 작성해주었다.&lt;/p&gt;
&lt;pre id=&quot;code_1762447258678&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;FROM --platform=linux/arm64 arm64v8/python:3.11-bookworm

WORKDIR /app


RUN apt-get update &amp;amp;&amp;amp; apt-get install -y --no-install-recommends \
    libgl1 \
    libglib2.0-0 \
    libgomp1 \
    &amp;amp;&amp;amp; rm -rf /var/lib/apt/lists/*


COPY consumer3.py .

RUN pip install \
    --break-system-packages \
    --no-cache-dir \
    redis \
    &quot;opencv-python-headless&quot; \
    numpy \
    torch \
    torchvision \
    ultralytics \
    pandas \
    requests \
    PyYAML \
    tqdm \
    matplotlib \
    seaborn

CMD [&quot;python3&quot;, &quot;consumer3.py&quot;]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>라즈베리파이 클러스터/영상데이터 분산처리</category>
      <category>k3s</category>
      <category>YOLO</category>
      <category>라즈베리파이</category>
      <category>분산처리</category>
      <category>쿠버네티스</category>
      <category>클러스터</category>
      <author>seolgugu</author>
      <guid isPermaLink="true">https://seolgu.tistory.com/23</guid>
      <comments>https://seolgu.tistory.com/23#entry23comment</comments>
      <pubDate>Fri, 7 Nov 2025 01:42:16 +0900</pubDate>
    </item>
    <item>
      <title>라즈베리파이 클러스터를 활용한 영상데이터 분산처리 (3) 프로토타입 구현</title>
      <link>https://seolgu.tistory.com/22</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;프로토타입의 구조&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클러스터에 올려야하는데 처음부터 모든걸 만들면서 시작할 수는 없으니,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 데이터가 흐르는 구조만 잡아보기로 했다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 일단 영상처리 모델은 올리지 않고, 영상처리를 한다고 가정하고 time.sleep()을 걸어서 연산하는것처럼 만들었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;gateway는 FastAPI로 구현했다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모델을 제외하면 camera - producer - redis - consumer - gateway - client 구조만 남게 되는데,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이걸 파드로 나누면 producer, redis, consumer, gateway 파드들이 필요하다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;camera가 연결된 producer는 1대인 infra-core 노드에 배치하고, (NodeSelector 활용)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;consumer들은 각각 ai-worker 노드에 배치,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;gateway, redis는 infra-core 노드에 배치해주었다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;최신 상태 버퍼 Redis&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원래는 메시지큐를 이용해 유실되는 프레임 없도록 하려고 하였으나,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;consume이 늦을 경우 실시간성이 사라지는 문제가 있어 최신 프레임의 정보만을 갖는 Redis를 사용하게 되었다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;redis에서 길이 1짜리 list를 사용했는데,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 하면 producer가 새로운 프레임을 RPUSH할 때마다 즉시 LTRIM을 수행해&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 마지막에 들어온 최신 프레임 1개만 유지하게 된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;덕분에 Consumer가 데이터를 늦게 가져가더라도 최신 프레임을 바로 처리할 수 있어 실시간성을 보장할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 BLPOP을 통해 데이터를 가져감으로써 한 번 처리된 프레임은 즉시 삭제되므로&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 consumer 파드가 동일한 프레임을 중복 처리하게되는 문제도 원천적으로 방지할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;처리량의 선형적 증가 검증&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI 모델 대신 time.sleep(0.2)를 사용해 consumer 파드의 1개당 처리능력을 5fps로 제한한 후,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파드 개수를 늘려가면 gateway로 들어오는 최종 fps를 측정했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파드 1개: 5fps&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파드 2개: 10fps&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파드 3개: 15fps&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실험 결과, consumer 파드를 추가할 때마다 전체 클러스터의 처리량이 선형적으로 증가함을 확인할 수 있었다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;향후 실제 AI 모델을 올렸을 때도 유연한 확장이 가능할 것으로 보인다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;717&quot; data-origin-height=&quot;628&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/plUxb/dJMcaiVV7nH/QvN6WPOYkPV11Ty0dhzZtk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/plUxb/dJMcaiVV7nH/QvN6WPOYkPV11Ty0dhzZtk/img.png&quot; data-alt=&quot;파드 1개&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/plUxb/dJMcaiVV7nH/QvN6WPOYkPV11Ty0dhzZtk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FplUxb%2FdJMcaiVV7nH%2FQvN6WPOYkPV11Ty0dhzZtk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;258&quot; height=&quot;226&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;717&quot; data-origin-height=&quot;628&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;파드 1개&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;727&quot; data-origin-height=&quot;615&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pH3Fx/dJMcaiVV7nN/NhVOserk6DYCZX4NB5hXXK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pH3Fx/dJMcaiVV7nN/NhVOserk6DYCZX4NB5hXXK/img.png&quot; data-alt=&quot;파드 2개&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pH3Fx/dJMcaiVV7nN/NhVOserk6DYCZX4NB5hXXK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpH3Fx%2FdJMcaiVV7nN%2FNhVOserk6DYCZX4NB5hXXK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;267&quot; height=&quot;226&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;727&quot; data-origin-height=&quot;615&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;파드 2개&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;711&quot; data-origin-height=&quot;605&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXex6Z/dJMcagjvVXa/mE1nDxHysuOUG3RuRr2PGK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXex6Z/dJMcagjvVXa/mE1nDxHysuOUG3RuRr2PGK/img.png&quot; data-alt=&quot;파드 3개&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXex6Z/dJMcagjvVXa/mE1nDxHysuOUG3RuRr2PGK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXex6Z%2FdJMcagjvVXa%2FmE1nDxHysuOUG3RuRr2PGK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;264&quot; height=&quot;225&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;711&quot; data-origin-height=&quot;605&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;파드 3개&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;발생한 문제&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에는 time.sleep(0.05)로 설정했어서 파드 하나당 20fps로 처리할 수 있었는데,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파드가 1개일때나 2개일때나 15fps가 나왔기에 처리량 증가를 확인할 수 없는 문제가 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;영상을 찍는 카메라 측의 하드웨어 성능 한계로 인한 병목인 것으로 보였기에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 검증하기 위해 consumer의 처리량을 인위적으로 낮춰(time.sleep(0.2)) 테스트를 진행했고,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처리량이 선형적으로 증가한다는걸 검증할 수 있었다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;향후 카메라 코드나 설정 최적화를 통해 성능을 개선할 예정이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;프로토타입 결과물&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;981&quot; data-origin-height=&quot;140&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/300F5/dJMcab3zURc/Ko1ajzyprB84hBfbYJpuL1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/300F5/dJMcab3zURc/Ko1ajzyprB84hBfbYJpuL1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/300F5/dJMcab3zURc/Ko1ajzyprB84hBfbYJpuL1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F300F5%2FdJMcab3zURc%2FKo1ajzyprB84hBfbYJpuL1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;981&quot; height=&quot;140&quot; data-origin-width=&quot;981&quot; data-origin-height=&quot;140&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 각 노드에 consumer를 하나씩 띄워놓은 상황이다.&amp;nbsp;&lt;/p&gt;</description>
      <category>라즈베리파이 클러스터/영상데이터 분산처리</category>
      <author>seolgugu</author>
      <guid isPermaLink="true">https://seolgu.tistory.com/22</guid>
      <comments>https://seolgu.tistory.com/22#entry22comment</comments>
      <pubDate>Wed, 5 Nov 2025 22:45:38 +0900</pubDate>
    </item>
    <item>
      <title>[k3s] 파드(Pod)에서 라즈베리파이 카메라 사용하기</title>
      <link>https://seolgu.tistory.com/21</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파이카메라 영상을 producer가 받아오기 위해서는 반드시 파드 내부에서 카메라에 접근할 수 있어야한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 로컬에서는 돌아갔으나 파드로 돌리기 위해 이미지 빌드를 하게되면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Raspberry Pi OS가 아닌 debian으로 빌드해야 하기 때문에 (공식 이미지가 없음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 libcamera가 설치되어있던 Raspberry Pi OS와 다르게 엄청난 의존성 에러를 뱉어낸다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;성공한 Dockerfile&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한번에 30분씩 걸리는 빌드를 20번 넘게 도전한 결과...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같은 도커파일로 빌드에 성공했다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1762347156695&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;FROM --platform=linux/arm64 debian:bookworm

ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update &amp;amp;&amp;amp; \
    apt-get install -y --no-install-recommends gnupg &amp;amp;&amp;amp; \
    echo &quot;deb http://archive.raspberrypi.org/debian/ bookworm main&quot; &amp;gt; /etc/apt/sources.list.d/raspi.list &amp;amp;&amp;amp; \
    apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 82B129927FA3303E

RUN apt-get update &amp;amp;&amp;amp; \
    apt-get install -y --no-install-recommends \
        python3.11 \
        python3-picamera2 \
        python3-redis \
        python3-opencv \
        git \
        libcap-dev \
        build-essential \
    &amp;amp;&amp;amp; apt-get clean \
    &amp;amp;&amp;amp; rm -rf /var/lib/apt/lists/*

WORKDIR /app
COPY producer2.py .


CMD [&quot;python3&quot;, &quot;producer2.py&quot;]&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;처음에 apt와 pip를 같이 썼는데 서로 덮어씌우고 난리가 났길래&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 파이썬 관련 패키지들&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;picamera2,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;numpy,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;opencv,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;redis&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;를 라즈베리파이OS가 공식 지원하는 apt 패키지로만 통일하여 설치했다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;쿠버네티스 권한 설정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 추가적으로 파드를 생성할 때 접근권한을 지정해줘야한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하드웨어 장치에 접근해야하기 때문에 아래와 같이 volumes를 지정해주고 volumeMount도 지정해줬다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1762347473432&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;apiVersion: apps/v1
kind: Deployment
metadata:
  name: producer-deployment
  namespace: evc 
spec:
  replicas: 1
  selector:
    matchLabels:
      app: producer
  template:
    metadata:
      labels:
        app: producer
    spec:
      nodeSelector:
        role: infra-core
      volumes:
        - name: udev
          hostPath:
            path: /run/udev
        - name: vchiq
          hostPath:
            path: /dev/vchiq
        - name: vcsm
          hostPath:
            path: /dev/vcsm
        - name: dma-heap
          hostPath:
            path: /dev/dma_heap
      containers:
        - name: producer
          image: yoonjaeko/evc-producer:12
          imagePullPolicy: IfNotPresent
          env:
            - name: REDIS_HOST
              value: &quot;redis-service&quot;
          securityContext:
            privileged: true
          volumeMounts:
            - name: udev
              mountPath: /run/udev
              readOnly: true
            - name: vchiq
              mountPath: /dev/vchiq
            - name: vcsm
              mountPath: /dev/vcsm
            - name: dma-heap
              mountPath: /dev/dma_heap&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>라즈베리파이 클러스터/영상데이터 분산처리</category>
      <author>seolgugu</author>
      <guid isPermaLink="true">https://seolgu.tistory.com/21</guid>
      <comments>https://seolgu.tistory.com/21#entry21comment</comments>
      <pubDate>Wed, 5 Nov 2025 22:02:10 +0900</pubDate>
    </item>
  </channel>
</rss>