반응형

 

 

지식 없이 완전 처음부터 하니.. 틀린정보가 많습니다..

 

https://cheongpark.tistory.com/54

 

SCARA 로봇 제작하기 Pt. 6 (제작 - 끝)

이제.. 다 조립했으니.. 보드에 선을 연결해야하는데.. 제일 헷갈린 부분이 여기다.. 최대한 찾아서 끼우긴 했지만.. 계속 잘 못 끼웠었었다.. 그러다가 결국엔 끼웠지만.. 저 사진에 보이는 것 처

cheongpark.tistory.com

여기에서 로봇을 모두 제작했었다.

그런데 한가지 문제가 있다.. 로봇을 제어할 프로그램이 필요한데.. 예제에서 제공하는 프로그램은 도무지 알 수도 없고.. 여러 버그도 있고 잘 되지 않는 문제들이 있다.. 

그래서 그냥 처음부터 프로그램을 제작하는 것을 목표로 잡았다..

 

구상

일단 GUI 프로그램으로 만들 예정인데..

나에게는 웹페이지로 GUI를 구현하는 방법, 프로그램으로 GUI를 구현하는 방법 2가지가 있었는데..

난 여기에서 프로그램으로 GUI를 만드는걸로 선택했다.

이유는 프로그램으로 GUI를 만들어 본적이.. 예전에 OpenCV로 비슷하게나마 만들어본게 끝이고.. 제대로 만들어본 적은 없고.. C++를 연습하기 위해서이다.

일단.. C++로 프로그램을 제작한다면.. MFC나.. WinRT 이런게 있는데.. 나는 나중을 생각해서 크로스 플랫폼이 지원되는 WinRT로 정했다.

 

그래서 Visual Studio에 WinRT 프로그램을 제작하기 위한 설치 파일을 설치한 후 프로젝트를 만들었다.

 

그 후 일단 구상을 했는데

대충 이런 느낌으로 제작하는 것이다. 메인 그리드 부분에선 Inverse Kinematics로 로봇의 암을 제어하고 오른쪽 설정 창에선 집게를 펼지 말지 이런거를 세팅하고, 왼쪽에선 높이로 로봇의 Z축을 제어하는 곳으로 정했다.

또한 아래쪽의 검은색 저부분은 각각의 세팅 값이다. 설정 창에서 저장버튼을 눌르면 아래에 스택이 쌓이고 각 스택을 눌르면 그 때 저장했던 값들이 다시 나오게 되는 프로그램을 제작하기로 했다.

 

현재도 제작중이기 때문에.. 저기에서 어떤 점이 바뀔지는 모르겠지만.. 이 상태로 하기로 정했다.

 

GUI Xaml 제작 및 프로그래밍

일단 여기에서 제일 중요한 부분은 Inverse Kinematics 부분이다. 물론 각도로 일일이 다 지정을 할 순 있겠지만.. 그렇게 하면.. GUI 프로그램을 만드는 의미가 사라진다..

그래서 일단 저기를 구현해야하는데.. 구현하기 전에 사전에 세팅을 했다.

 

그리드 그리기

먼저 그리드를 표시하는 것!

일단 Xaml로 저것이 표시될 구간을 정한다!

현재 나의 경우엔.. 이걸 처음하다보니.. 아는게 없었다.. 그래서 어느정도 전문가가 보기엔 불편한 것들이 많겠지만.. 일단 이대로 진행하기로 했다. 아래 코드 구조에서 Canvas가 2개가 있는데.. 하나는 그리드를 표시하는 용이고 하나는 Inverse Kinematics로 팔 부분을 표시하는 것이다.

<Border
    Width="506"
    Height="506"
    BorderBrush="#f8f8f2"
    BorderThickness="3"
    CornerRadius="15,15,15,15"
    RelativePanel.AlignVerticalCenterWithPanel="True"
    Margin="200, 0, 0, 0">
    <!-- 그리드 위에 컨트롤를 넣는 느낌으로 할려 했지만 그리드가 나중에 렌더링 되어서 Canvas.ZIndex로 직접 바꿈 -->
    <Canvas
        x:Name="DrawGrid"
        Width="500"
        Height="500"
        Canvas.ZIndex="0"
        Background="Transparent"> 
        <Canvas
            x:Name="ControlJoint"
            Width="500"
            Height="500"
            Canvas.ZIndex="1"
            Background="Transparent"> <!-- 배경을 투명하게라도 주는 이유는 안하면 ControlJoint로 마우스 위치를 얻을려고 하면 Shape 부분만 얻을 수 있어서.. 전부 얻기 위해서 하는거 -->
        </Canvas>
    </Canvas>
</Border>

주석에 달린 것 처럼.. ZIndex를 넣은 이유가.. 그리드 배경 위에 팔 부분이 나오면 좋겠지만.. 렌더링 되는 것이.. 그리드가 먼저 되다보니.. ZIndex로 직접 바꾼거다.. 그리고 움직일 부분에서 마우스로 제어할 것인데.. 거기에서 마우스로 제어하는 경우 그리드에선 전부 추적이 가능하지만.. ControlJoint에선 팔 부분만 마우스의 좌표를 알 수 있다.. 그래서 그냥 배경을 추가하는 방식으로 진행했다.

 

이제 저렇게 하면 프로그램 안에 500 * 500 의 사각 박스가 나오게 된다.

이 사각 박스 안에 격자를 그려야하는데 이걸 위해 함수를 만들었다.

일단 line의 경우 좌표에서 필요한 속성은 X1, Y1, X2, Y2가 있다.

그래서 내가 생각한 방법으론 500을 내가 필요한 만큼의 라인 갯수로 나눠서 각 지점에 직접 배치하는 방식으로 했다.

 

그렇게 해서 C++ 코드를 작성했다.

void MainPage::DrawLine(Xaml::Shapes::Line& line, Xaml::Controls::Canvas& canvas, double thickness, float2 pos_1, float2 pos_2, Xaml::Media::Brush color) {
    // 위치나 색 설정
    line.X1(pos_1.x);
    line.Y1(pos_1.y);
    line.X2(pos_2.x);
    line.Y2(pos_2.y);

    line.StrokeThickness(thickness);
    line.Stroke(color);

    canvas.Children().Append(line);

    Xaml::Controls::Canvas::SetZIndex(line, 0);
}

void MainPage::DrawGridLines(int grid_x_count, int grid_y_count) {
    double grid_width = DrawGrid().ActualWidth();
    double grid_height = DrawGrid().ActualHeight();
    double line_thickness = 1;

    // 가로 줄 세로로 여러개 그리는거
    for (double i = grid_height / grid_y_count; i < grid_height; i += grid_height / grid_y_count) {
        Xaml::Shapes::Line line = Xaml::Shapes::Line();
        DrawLine(line, DrawGrid(), line_thickness, float2(0, i), float2(grid_width, i));
    }

    // 세로 줄 가로로 여러개 그리는거
    for (double i = grid_width / grid_x_count; i < grid_width; i += grid_width / grid_x_count) {
        Xaml::Shapes::Line line = Xaml::Shapes::Line();
        DrawLine(line, DrawGrid(), line_thickness, float2(i, 0), float2(i, grid_height));
    }
}

이 코드로 DrawGridLines를 처음에 프로그램을 시작할 때 실행해서 각 x축으로 몇개 y축으로 몇개 넣을지 선택해서 하면 

 

결과적으로 이렇게 표시가 된다..!

라인을 각각 10개씩 넣어서 했다.

 

마우스 위치 알아내고 표시하기

그리고 이후에 팔을 제어하기 위해 마우스를 사용해야해서 마우스 포인터의 위치를 알아야 한다..!

근데 일단 보통은 콘솔창에서 확인을 하는데.. 콘솔창은 어떻게 띄우는지도 모르겠고.. 그냥 GUI 화면에서 확인하는게 빠를 것 같아서 GUI 화면에서 표시되도록 했다..!

 

일단 Xaml 코드에선

<StackPanel
    BorderBrush="White"
    BorderThickness="2" RelativePanel.AlignBottomWithPanel="True" RelativePanel.AlignLeftWithPanel="True">
    <StackPanel
        Orientation="Horizontal">
        <TextBlock
            Width="50"
            TextAlignment="Center"
            Text="X"
            FontSize="35"/>
        <TextBlock
            x:Name="Point_X"
            Width="100"
            TextAlignment="Right"
            Text="0"
            FontSize="35"/>
    </StackPanel>
    <StackPanel
        Orientation="Horizontal">
        <TextBlock
            Width="50"
            TextAlignment="Center"
            Text="Y"
            FontSize="35"/>
        <TextBlock
            x:Name="Point_Y"
            Width="100"
            TextAlignment="Right"
            Text="0"
            FontSize="35"/>
    </StackPanel>
</StackPanel>

이런식으로 했다. X인지 Y인지 알 수 있게 하고 그 바로 옆에 숫자를 표시하도록 했다.

그래서 이걸로 해서 실행하면 저런식으로 나온다.

 

그리고 각 X, Y 좌표를 얻어야 한다.

이 경우엔 좀 간단한데.. 보통은 Xaml 코드에서 X, Y 값을 가져올 함수를 지정할 순 있지만.. 나는 나중에 함수 이름을 쉽게 변경하기 위해 모두 C++에서 진행했다.

일단 X, Y 좌표를 가져올 캔버스는 ControlJoint라는 것이기 때문에 여기의 PointerMoved로 접근해서 함수로 넘겨주는 방식으로 했다.

void MainPage::Init() {
	ControlJoint().PointerMoved({ this, &MainPage::JointControlCanvasPointerMoved });
}

void MainPage::JointControlCanvasPointerMoved(IInspectable const& sender, Xaml::Input::PointerRoutedEventArgs const& e) {
    Input::PointerPoint point = e.GetCurrentPoint(ControlJoint());
    float2 point_pos(point.Position().X, point.Position().Y);

    Point_X().Text(to_hstring(point_pos.x));
    Point_Y().Text(to_hstring(point_pos.y));
}

이런식으로 하면 마우스 포인터의 값을 가져와서 아까 만들었던 Text로 집어넣게 된다.

Init 함수는 그냥 임의로 만든거고.. 프로그램이 시작할 때 실행되도록 하면 된다. 그렇게 해서 마우스 값을 넘겨주고 거기에서 X, Y 값을 뽑아서 Text를 지정하는 방식이다.

 

결과물!!

그래서 이것으로 일단 프로젝트 준비는 끝났다..!!

이걸로 지금까지 한 것의 결과물을 보면 아래 처럼된다..!

그렇게 해서 일단 Pt. 1은 끝났다..! 

이 모든 것이.. 3일 정도 걸려서 알아내고 만든 결과다..! 물론 GPT의 도움도 받긴 했지만.. 암튼.. 다음에선 IK를 구현하는 것이다..!

반응형
반응형

이제.. 다 조립했으니.. 보드에 선을 연결해야하는데.. 제일 헷갈린 부분이 여기다..

최대한 찾아서 끼우긴 했지만.. 계속 잘 못 끼웠었었다.. 그러다가 결국엔 끼웠지만..

 

저 사진에 보이는 것 처럼 앞쪽에 점퍼핀 노란색이 보일꺼다.. 저게 CNC 쉴드에서 빨간색 부분에 모터 드라이버 끼우는 곳이 있는데 거기의 모터를 제어를 킬꺼냐 말꺼냐이다.. 끼우면 키는거.. 저걸 처음에 몰랐어서 왜 안되지라고 생각했는데.. 검색해보니 어쩌다 알게 되었다. 그 후에는 좀더 잘 움직이게 하기 위해

안쪽에도 점퍼핀을 끼웠다. 달라지는건 좀더 여러 스텝으로 제어할 수 있는 것 같다. 근데.. 저 점퍼핀.. 원래 나는 점퍼핀이 딱히 필요가 없어서 사지를 않았었는데.. 당장 필요하다보니..

여러곳에서 뜯어서 사용했다.. 현재는 점퍼핀을 사고 다시 끼운 상태이지만.. 진짜 있는거 다 뒤져서 점퍼핀을 뺐는데.. 딱 필요한 만큼만 있었다.. 아슬아슬했지만.. 겨우 끼운 후에 어느정도 완성할 수 있었다.

 

근데 한가지 단점인건.. 가만히 세워두면 지 혼자 고꾸라진다..

 

이걸 해결하기 위해서는 아래에 판이 필요한데 이 판을 따로 구매하는건 너무 돈 낭비 같아서.. 다이소를 갔다.

그랬더니.. 딱 나에게 필요한 나무판자가 있었다. 바로.. 도마!

기억도 안나는 크기를.. 대충 프린트기 사이즈를 생각해서 된다는걸 알고 바로 사왔다..!

 

그리고 바로 하단부를 고정시키기 위해 하단부의 평면을 Fusion 360에서 가져왔다.

이렇게!.. 신기한건 딱 하단부하고 맞는다는 것..

SCARA 하단 단면.pdf
0.09MB

 

여기에서 다운받으면 된다!

암튼 저걸 이용해서 풀로 붙인다. 근데 붙일 때 도마를 감싸고 있는 비닐은 안때고 붙였다. 이유는 붙일 때 비닐에 붙게 하고 나중에 비닐만 제거해서 종이를 뗄 수 있기 때문!!

 

붙인 후에는 잘 맞춰서 드릴로 뚫어주고

누구나 있는 이 드릴 비트를 이용해서 flat 나사가 들어갈 구멍을 뚫어주었다.

뚫을 때 기준을 안세워서.. 전부 크기가 달르긴 하지만.. 전부 잘 들어간다!.. 그리고 놀라운건 테스트로 끼워봤는데 하단부하고 정확하게 일치한다..!

 

근데.. 여기부터는 사진을 찍지는 않았는데.. 저기에 너트를 넣는데.. 문제가 발생했다.. 저 사이에 서포터를 만들어서 출력하는데 서포터를 제거하면서 저 부분이 헐렁해져서 너트가 헐렁하게 끼워져서 도마를 끼운 상태에서 계속 헛돌아서.. 빼는데.. 결국에 안빠진다.. 그래서 그냥 강제로 비틀어서 다시 출력할 생각으로 망가트렸다.. 결국엔 망가져서 다시 출력하고 출력하는 겸 나머지도 다시 재출력해서 흰색에서 대부분 파란색으로 바뀌었다.. 왜냐면 학교에서 필라멘트를 4개를 그동안 동아리에서 다른 팀꺼 출력해준 덕분이라면서 사주셨는데.. 그 중 하나가 파란색 필라멘트이기 때문이다..

 

암튼 재출력 했는데도.. 헐렁했다.. 이유는 뭐.. 그냥 프린터가 캘리브레이션이 되었는지 그냥 헐렁하다..

 

솔직히 이 문제는 해결할 수 없어서.. 다이소가서 순간접착제를 살려고 했는데.. 나는 미성년자라는 것이다..

그래서 나중에 부모님하고 이동할 때 한번 다이소 같이 가자 해서 그때 샀다.. 근데 항상 순간접착제를 살 때 마다 항상 어디론가 부모님이 쓰실려고 하면서 사라지는데.. 그것 때문에 그냥 2개를 샀다..

 

암튼 그걸로 단단하게 고정시키고 하루정도 말린 후에 끼웠는데.. 모두 다 헛돌지 않고 잘 돌아간다..! 심지어 너트 사이까지 다 들어가서 좀 돌리는데 빡세긴 했다.. 암튼 전부 제작해서 

이렇게 완성했다!!!

선 정리하는건 알리에 쉽게하는게 있길래 바로 사서 했다..!

암튼 흰색으로 만들려던게 완전 파래지긴 했는데.. 진짜 고정도 잘 되고 잘 되었다!!

 

그리고 선을 끼울 때 헷갈리기도 해서.. 한번 다 끼우고.. 알리에서 수축튜브에 글 새길 수 있게 해주는 카트리지가 있길래 그것도 사서 저렇게 모두 정리를 했다!!

 

근데 이제부터가 진짜 문제이다. 

나는 이걸 제작하기로 한건 그냥 재미를 위한 것인데.. 학교에서 발표를 해야하다보니.. 인공지능과 결합해야한다..!

근데 결합할려면 이 로봇을 제어하는 프로그램이 필요한데.. 기본 예제로 주어지는 프로그램은.. 너무 이상하기도 하고 제어가 멋대로 된다.. 그냥 그 프로그램은 진짜.. 별로다라고 생각된다.. 그리고 펌웨어에도 여러가지 문제가 있어서 전부 내가 제작하기로 했다.

 

시간 안에 다 할 수 있을진 모르겠지만.. 이 글을 쓰는 현재도 제작 중이다.

 

현재 글을 쓰는 기준으로 만든 것 까지 보여준다면

이렇게 만들고 있다. 저 중앙 부분이 로봇의 팔 부분이다. 근데.. Inverse Kinematics를 사용해야하다보니.. 어렵긴 한데.. 다행히 2개의 팔의 경우 삼각함수로도 가능하기 때문에 이걸로 현재 계속해서 만들고 있다. 처음 해보는 GUI 프로그래밍이긴 한데.. 일단 최대한 해보고 있다. 또한 C++로 제작하고 있다..! 심지어 크로스 플랫폼으로 작동 될 수 있도록 WinRT/C++로 제작하고 있다..!

반응형
반응형

이전 글과 바로 이어집니다!

 

어느정도 완성한 후에는 바로 테스트를 위해 메인보드를 설치했다.

필요한건 아두이노 우노(호환보드), CNC 쉴드였다. 아두이노 우노를 호환보드로 한건.. 엄청 저렴하기 때문이다. 2만원을 3천원에 살 수 있는데 성능은 거의 똑같다는.. CNC 쉴드는 우노에 바로 끼워서 사용할 수 있는 모터 제어기?다 노란색이나 빨간색 핀에 모터 드라이버를 끼우면 바로 모터를 돌아가게 할 수 있다! 

 

여기에서 모터드라이버는 일단 A4988를 쓰긴 했는데.. A4988이게.. 모터 소음이 굉장하다.. 그래서 처음에 조립하고 돌려볼 때는 모터 소음이 너무 심해서 TMC2209를 사서 끼워볼까 했는데.. 가격도 비싸고 모터 드라이버가 버티기 힘들 것 같아서 그냥 A4988로 했다.. 나중에 해보니 소음의 원인은.. 이전 글에 있던 팔을 지탱하는 부분의 유격 때문에 잘 고정되지를 않아서 발생하는 소음이였다.. 근데 만약 TMC2209를 했다면.. 센서리스 홈 이나 소음을 줄일 수 있을텐데.. 어차피 코드를 못 짜서 못할 것 같긴하다..

 

그리고 일단 아두이노를 끼우는데.. 문제가 발생했다.. 끼우는 곳에 원래는 flat 볼트를 사용해야한다.. 근데 구매를 일반 렌치 볼트로 해버려서 고정을 시키면 들뜨는 문제가 발생한다.. 이건 나중에 캐드로 수정해서 육각 렌치 볼트도 되게 바꿔서 문제를 해결했다.. 암튼 전부 끼우고

 

전선을 끼우는데.. 사진에는 없지만 좀 큰 문제가 있었다.. 선의 위치를 모른다는 것이다.. 최대한 맞춰서 끼워봐도.. 뭐가 뭐인지도 제대로 알 수가 없었다.. 그래도 하나씩 찾아가며 위치를 찾고해서 결국엔 찾긴 했다.

근데 또 문제가 발생했다.. 모터는 정상적으로 작동하는데 리미트 스위치가 제대로 인식이 안되는 것 같다.. 그래서 따로 코드로 리미트 스위치의 값을 읽어서 봤더니.. 계속 True를 출력하고 있었다..

 

이유를 생각해봤는데 그냥 접촉불량 같다.. 그래서 처음에는 듀폰 핀을 내가 직접 끼워서 하다보니 여기에 문제가 생긴줄 알고 했지만.. 아니였다.. 리미트 스위치 부분이 그냥 선이 제대로 끼워지지 않은 거였다.. 

 

전부 분리하고 다시 조립해서 결국엔 다 되었다..

근데 하면서 놀라운건.. 진짜 이젠 찝는데 고수가 된 것 같다.

학교에 디바이스과가 있는데 저번에 찝는 모습을 보니.. 완전 정석대로 하다보니 불필요하게 선을 버리기도 하고.. 너무 이상하게 했었다.. 근데 나는 유튜브를 보면서 혼자 익히게 되다 보니.. 뭔가 되게 잘 되었다..

 

암튼 그 후에 작동 시켜보았다.

이전에 말한 것 처럼.. 유격 때문에 소음이 굉장하긴 하지만.. 암튼 잘 움직인다!!

 

그리고 집게를 조립시켜야한다.. 이게 다른 것보다 좀 어려웠던 것 같다..

재료를 전부 출력해주고 조립을 했다. 

여기에서 일단 모터를 MG946R인가를 사용하는데 기본으로 제공하는 날개? 를 조립하는데 저게 구멍이 크기가 안되서.. 일단 드릴로 뚫어서 어찌저찌해서 끼운 후에.. 돌려봤는데.. 어디선가 걸린다.. 3번째 사진의 아래쪽에 보이는 너트와 걸리는 것이다..

볼트 머리는 이만큼이나 틔어나와있는데.. 볼트가 너무 크다보니 너트하고 걸려서 끼워지질 않는다.. 락 너트 말고 일반 너트로 해도 마찬가지였다.. 그래서 결국엔 그냥 모델링을 수정했다..

이렇게 2개를 비교했는데 왼쪽이 수정한 모델이다. 육각 너트가 들어갈 구멍을 잘 해서 뚫었다. 진짜 신기한건.. 이때는 3D 프린터에 캘리브레이션을 한 상태여서 너트가 진짜 딱 맞게 들어갔다.. 모델링 수정은 Fusion 360에서 했었다.

그리고 끼웠는데

다행히도 너트에 안걸린다!!

 

근데.. 또 문제가 발생했다..

또 안돌아간다.. 그래서 모터를 이리저리 움직이면서 왜 그런지 했는데.. 모터의 이름을 표시할려고 놔둔 곳이 틔어나와있어서.. 안돌아가는 것이였다.. 그래서 그냥 갈아서 끼웠다.

그리고 해보니!! 잘 작동했다!!!!

그 후엔 어려움 없이 전부 조립했다.

뭔가.. 너트가 들어가는 부분이 굉장히 좁아보이긴 하지만.. 그래도 잘 만들어졌다..

이렇게 한 후에 로봇에 붙일려는데.. 또 문제가 발생했다..

 

아까와 같은 문제인데 너트가 flat 볼트 모양으로 된거여서.. 이것도 육각 렌트 볼트로 모델링을 수정해서 다시 출력하고 끼웠다.. 이런 문제 덕분에.. Fusion 360을 모델링 할줄은 모르는데 수정하는 방법을 터득할 수 있었다.. 하하하하

 

그 후에 장착도 해주고 선도 연결했다.. 근데 선을 연결할 때 원래는 로봇 안에 넣는데.. 그냥 나는 나중에 확장성을 위해서 밖으로 뺐는데.. 후회된다..

 

그리고 이전에 말했던 것에서 틔워나왔던 부분도 다시 모델링 수정해서 출력해서 잘 고정시킬 수 있었다.

저거 색이 중간에 틀어진건.. 필라멘트가 모잘라서 바꾼건데.. 뭔가 더 멋지게 바뀌었다..!

 

다음 글에서 이어집니다!

반응형
반응형

이제 하단부 위의 팔 부분을 만들어야 한다.

 

여기가 제일 어려웠고.. 재출력을 몇번이나 계속 했던 부분이다..

 

일단 팔 부분을 지탱할 부분을 만들어야 한다. 저번 글에서 이어지는데 

이 부분을 조립한다. 하단 부분 위에 부품을 올려서 볼트와 너트로 조립을 했다.. 근데 조립을 해보면서 알게된건.. 영상에선 분명 육각 볼트를 사용하라 해서 했는데 겉으로 보이지도 않고 하니.. 그냥 일반 육각 렌치 볼트로 하는게 좋을 것 같다.. 그리고 저 부분을 단단하게 조립하고 하단 부분에 끼우는걸 추천한다.. 아니면 제대로 조립하기도 어렵고 잘 되지를 않는다.

그 후엔 10 * 400mm 선형 봉을 끼운다. 여기에서 어려운건 끼우는 구멍이 좁았던지라 잘 안끼우면 다 들어가질 않아서 마지막꺼를 끼울 때 제대로 안들어갈 수 있다. 그렇기 때문에 최대한 끼우고 마지막에 덮개로 안보이게 해준다.

 

그 후엔 이 부분을 조립한다.

여기도 어려웠는데.. 저기 끼워져있는게 선형베어링이다.. 근데 저게 지름이 29mm인데.. 3D 프린터가 캘리브레이션이 안되어있어서.. 끼워야하는 부분의 내부 지름이.. 29mm보다 좀 많이 작았다.. 그래서 최대한 주위를 갈아서 그나마 억지로 끼웠는데.. 다 조립한 후에는 한번 저 부분을 완전 교체했다.. 이유는 너무 갈아서 헐렁하기도 했었고.. 갈면서 약간씩 오차가 발생했다.. 그래서 위 아래로 움직일 때 마다 이상한 소리가 나기도 하고 여러가지 문제가 많았다.. 그래서 무조건 추천하는건 칼리브레이션을 해서 오차를 줄인 후에 출력하고 넣는 것이다.. 나중에 새로 출력한 부품은 정확하게 들어갔다.

 

저 부분이 제대로 안되면 무거운 팔을 들고 있어야 하는 부분이기 때문에 팔이 쳐져서 Z 축으로 제대로 들어올려지지 않게 될 수도 있다.

 

그후엔 팔을 제어할 수 있는 모터를 끼우고 GT2 타이밍 풀리와 8mm 리드 스크류 너트? 를 고정시킨다.

 

그 후에는 팔을 조립한다.. 

팔을 조립하는 과정은 따로 안담은게.. 찍어놓은 사진도 딱히 없고 굳이 할 필요는 없을 것 같다.

근데 제일 중요한 것은 이거다.

팔의 중심 부분인데. 여기가 가장 중요하다. 만약 여기가 헐렁하게 끼워지면 나중에는 팔이 잘 안돌아가거나 바로 망가질 수 있다. 그래서 최대한 잘 끼워지진 않지만.. 강제로 끼웠다. 만약 이 곳이 헐렁하거나 너무 쉽게 끼워진다면 의심을 해야할 수도 있다..

 

그 후엔 아까 만들었던 하단 부에 잘 맞춰서 아래처럼 끼운다.

솔직히 여기가 좀 많이 까다로웠다.. 선형봉이 수직으로 일자로 뻗어있었다면 좋았겠지만.. 바깥으로 좀 벌려진 상태였다.. 그래서 이걸 최대한 맞춰서 끼워야 해서.. 잘 넣기가 어려웠다.. 심지어 무겁기도 해서..

 

그렇게 끼운 후에는 윗 부분을 조립한다.

윗 부분에도 마찬가지로 리미트 스위치를 끼우고 위쪽을 끼운다. 근데 여기에서 나는 하단부에서는 선형봉을 조이는 부분에 볼트와 너트를 이용해서 조였지만.. 여기에선 조이지 않았다. 충분히 잘 고정되기도 하고 해보니 조여봤자.. 조이지 않은거와 별 차이가 없었다.

 

그리고.. 다이아몬드 톱으로.. 리드 스크류를 잘랐다.. 이걸 잘른 이유가.. 원래는 영상에서 나오는 것 처럼 28mm인가? 를 잘른거를 사면 됬었는데.. 그냥 되겠지.. 하고 사버려서.. 버릴 수도 없고 해서.. 집에 남아있는 다이아몬드 톱으로 엄청 갈았다.. 진짜 안갈리는걸 강제로 계속 갈아서 결국 1시간만에 다 갈 수 있었다.. 절단면은 좋진 않지만.. 뭔가 뿌듯했다.

 

그 후엔 리드스크류를 끼우고 커플러도 끼우고 모터도 끼우고 해서 어느정도 완성을 했다.

 

이후껀 다음 글에서!

반응형
반응형

원인

필요한 헤더파일이 안불러와진 것..

 

문제

WinRT로 프로그램을 만드는 중에.. 어떤 오류가 발생했다.. 

심각도 코드 설명 프로젝트 파일 줄 비표시 오류(Suppression) 상태
오류 C3779 'winrt::impl::consume_Windows_UI_Input_IPointerPoint<winrt::Windows::UI::Input::IPointerPoint>::Position': 'auto'을(를) 반환하는 함수를 정의되기 전에 사용할 수 없습니다.	ScaraGUIController	C:\Users\PKDPMS0328\source\repos\ScaraGUIController\ScaraGUIController\MainPage.cpp 22

이 오류는 WinRT 부분에서만 일어나는 오류 같은데.. 블로그나 해결 방법은 잘 안나와 있어서.. 일단 마이크로소프트 문서에 검색해보니..

https://learn.microsoft.com/ko-kr/cpp/error-messages/compiler-errors-2/compiler-error-c3779

 

컴파일러 오류 C3779

자세한 정보: 컴파일러 오류 C3779

learn.microsoft.com

해결 방법은 다행히 있었다..!

 

해결방법

어쨋든 내 코드의 경우 

#include <winrt/Windows.UI.Xaml.Input.h>

void function(winrt::Windows::UI::Xaml::Input::PointerRoutedEventArgs const& e) {
	winrt::Windows::UI::Input::PointerPoint point = e.GetCurrentPoint(ControlJoint());
    
    	Point_X().Text(winrt::to_hstring(point.Position().X));
    	Point_Y().Text(winrt::to_hstring(point.Position().Y));
}

대충 이런식의 코드인데.. 여기에서 오류가 난 부분은 point.Position().X 저쪽 부분이다..

여기에서 문제의 저 오류에 winrt::Windows::UI::Input::IPointerPoint 이런게 뭐가 문제가 있다면서 알려주는데

이것을 헤더파일에 추가하면 문제가 해결되는 것이였다..!

 

그래서 나의 경우에는 IPointerPoint는 Input 헤더 안에 있는 것이기 때문에 

#include <winrt/Windows.UI.Input.h> 이 코드로 헤더파일을 추가해서 해결했다..!

#include <winrt/Windows.UI.Xaml.Input.h>
#include <winrt/Windows.UI.Input.h> // 오류 해결에 필요한 헤더파일

void function(winrt::Windows::UI::Xaml::Input::PointerRoutedEventArgs const& e) {
	winrt::Windows::UI::Input::PointerPoint point = e.GetCurrentPoint(ControlJoint());
    
    	Point_X().Text(winrt::to_hstring(point.Position().X));
    	Point_Y().Text(winrt::to_hstring(point.Position().Y));
}

 

결론

'winrt::impl::consume_Windows_UI_Input_IPointerPoint<winrt::Windows::UI::Input::IPointerPoint>::Position': 'auto'을(를) 반환하는 함수를 정의되기 전에 사용할 수 없습니다.

 

이런식으로 오류가 뜰 경우

1.  <winrt::Windows::UI::Input::IPointerPoint> 부분이 자신의 오류에서 뭐인지 찾는다.

2. winrt::Windows::UI::Input::IPointerPoint 이것에 해당하는 헤더파일을 찾는다. 보통은 맨 뒤에꺼 지운게 아마 헤더파일일 꺼다.. winrt::Windows::UI::Input 여기까지, 그리고 헤더파일로 할 경우 winrt/Windows.UI.Input.h

3. 찾은 헤더파일을 추가해서 문제를 해결한다!!!!

 

근데.. 애초에 Input::PointerPoint가 필요한 헤더파일이 winrt/Windows.UI.Input.h였다.. winrt/Windows.UI.Xaml.Input.h가 아닌... 그냥.. 필요한 헤더파일을 안불러왔었던 것.. 

반응형
반응형

그저께 부턴가 윈도우 업데이트 하면서 갑자기 이런 오류가 꺼도 꺼도 계속 떴다..

찾아보니 NProtect가 날뛰고 있던 것.. 은행 백신 때문에 깐 거였는데..

 

바로 지워버리니 해결..

반응형
반응형

빠르게 사용하기 위해 제작된 글 입니다! 제대로 된 설치나 실행코드가 아닐 수 있습니다!

일단 이것을 도전한다면 아나콘다나 미니콘다는 설치해주세요.

설치 안해도 되지만 관리하기가 편하기 때문에 설치하는 것이 좋습니다!

 

속도 테스트 영상 (제가 찍었습니다.)

 

SDXL Turbo란

2023년 11월 28일.. 바로 이 글을 쓰는 2일전에 나온 것이 SDXL Turbo입니다.. ㄷㄷ

원리나 자세한 것은 잘 모르지만 보통 Stable Diffusion으로 이미지를 만들 때 step 수를 늘려서 20~50 정도로 스텝을 반복하면서 이미지를 만듭니다. 그런데 SDXL Turbo는 이런 스텝 없이 한번의 스텝으로 이미지를 완성한다는 것이죠..

 

일반 Stable Diffusion은 이미지에 노이즈가 잔뜩 끼어있는데.. 이러지 않고 바로 완성된 이미지를 생성한다는 것.. 엄청난 기술..!

https://stability.ai/news/stability-ai-sdxl-turbo

 

Introducing SDXL Turbo: A Real-Time Text-to-Image Generation Model — Stability AI

SDXL Turbo is a new text-to-image mode based on a novel distillation technique called Adversarial Diffusion Distillation (ADD), enabling the model to create image outputs in a single step and generate real-time text-to-image outputs while maintaining high

stability.ai

아무튼 이런 SDXL Turbo를 직접 컴퓨터에서 돌려볼 수도 있도록 오픈소스로 풀렸기 때문에 바로 사용해봅시다!

기본적으로 모든 방법은 이 링크 아래에 있습니다.

https://huggingface.co/stabilityai/sdxl-turbo

 

stabilityai/sdxl-turbo · Hugging Face

Inference API has been turned off for this model.

huggingface.co

 

1. 가상환경 만들기

일단 가상환경을 만들겠습니다.

Anaconda Prompt를 열어주고 아래 명령어를 입력해주세요!

conda create -n SDXLTurbo python=3.10 -y

이렇게 하면 자동으로 가상환경을 만들어지게 됩니다.

여기에서 제가 따로 테스트 했을 때 파이썬 3.10 버전에서도 됬기 때문에 3.10으로 했습니다.

 

그 후에 만들어진 가상환경을 활성화 시킵니다.

conda activate SDXLTurbo

이렇게 하면 가상환경이 활성화 되면서 커맨드 창의 왼쪽에 (base) 가 (SDXLTurbo)로 바뀌었을 겁니다!

 

2. 라이브러리 설치

이제 라이브러리를 설치해야합니다!

일단 GPU를 사용할 것이기 때문에 Pytorch를 설치하고 나머지는 제공되는 것을 설치할 것입니다. 

https://pytorch.org/get-started/locally/

 

Start Locally

Start Locally

pytorch.org

일단 여기에 가서 자신의 OS, 자신의 CUDA 버전에 맞춰 명령어를 만든 후에 이걸 입력해서 설치해줍시다!

저의 경우 아래 처럼 나왔기 때문에 아래 명령어로 설치했습니다. (설치할 때 kaggle 뭐라면서 빨간색 뜨는건.. 아마 무시해도 될겁니다..;;)

pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121

 

설치가 완료 되었다면 2번째로 이미지 생성에 필요한 라이브러리를 설치해줘야 합니다! 설치 명령어는 허깅페이스에도 나와있습니다.

아래 명령어로 설치해주시면 됩니다.

pip install diffusers transformers accelerate --upgrade

 

설치가 되었다면 모든 준비는 끝났습니다!

 

3. 코드 입력 및 실행

여기에서 실행하는건 2가지 방법이 있습니다.

첫번째 방법은 커맨드 창에 python을 적고 엔터 눌른 후에 아래에 적힌 코드를 입력해서 실행하는 방법이 있지만 이건 제대로 확인하기도 어렵고 좀 별로인 방법이기 때문에 두번째 방법으로 하겠습니다.

두번째 방법은 

일단 Visual Studio Code를 엽니다!

그 후 프로젝트 폴더를 생성한 후에 그 안에 main.py든 아무 파이썬 파일을 생성합니다.

그리고 main.py를 열고 그 아래 

대충 이런 느낌의 하단 바가 있을겁니다. 여기에서 3.11.2 64-bit 쪽의 버튼을 클릭합니다. (버튼의 버전 등은 다를 수 있습니다.)

그러면 인터프리터 선택창이 나오는데 여기에서 아래와 비슷한 것을 찾아 선택합니다.

만약 없다면 오른쪽 상단의 새로고침이나 Visual Studio Code를 종료했다가 다시 열어보세요!

 

그 후에 아래 코드를 입력합니다. (아래 코드는 원본 코드에서 조금 변화 시켰습니다. 시간 측정 코드, 무한 입력 코드, 이미지 저장 코드 들을 추가했습니다.)

from diffusers import AutoPipelineForText2Image
from torchvision.transforms.functional import to_pil_image
from torchvision.transforms import ToTensor
import torch
import time

pipe = AutoPipelineForText2Image.from_pretrained("stabilityai/sdxl-turbo", torch_dtype=torch.float16, variant="fp16")
pipe.to("cuda")

while True: # 반복
    prompt = input("prompt: ") # 프롬프트 입력

    start_time = time.time() # 시간 측정 1
    image = pipe(prompt=prompt, num_inference_steps=1, guidance_scale=0.0).images[0] # 이미지 제작
    end_time = time.time() # 시간 측정 2

    # 이미지 저장을 위해 PIL 이미지로 변환
    tensor_image = ToTensor()(image)
    image = to_pil_image(tensor_image)

    print(f"제작된 시간: {round((end_time - start_time) * 1000, 2)}ms") # 측정된 시간 출력 밀리초로
    image.save("image.jpg") # 이미지 저장

그 후에 Ctrl + Shift + ` 를 동시에 눌러서 새 터미널을 엽니다. 

그리고 python main.py를 입력해서 실행합니다! main.py 말고 다른 이름으로 해주었다면 그 이름으로!

 

아무튼 그러면 실행이 되고 자동으로

C:\Users\<컴퓨터 이름>\.cache\huggingface\hub

위 경로 안에 필요한 SDXL Turbo 모델을 다운로드 하게 됩니다. 약 6.46GB입니다.

 

모든 것이 정상적으로 설치되었다면 아래 처럼 뜰 것입니다. (prompt: )

그 후에 원하는 프롬프트를 입력해서 이미지를 생성합니다. 이미지는 현재 프로젝트 파일의 image.jpg에 생성됩니다.

이미지는 한번 생성하고 또 생성하면 이미지가 변경됨으로 마음에 드는 사진이 있다면 만든 후에 백업해야 합니다!

 

나머지

이미지를 생성할 때 한번은 2~10초 정도 느리게 생성됩니다. 이건 아마 모델의 최초 로드 하고 연관이 있는 것 같습니다.

그 후에는 제 컴퓨터 기준으로 (RTX 3080TI) 약 0.2초 만에 생성이 됩니다.

 

암튼 잘 되네요! 다만 상업적이용이 아직은 불가하므로 주의해주세요!

반응형
반응형

모든 조사를 마무리 했으므로 조립을 시작했다.

일단 하단부를 조립해야한다.

이 부분을 조립해야한다...

 

제일 크면서도 무겁고 출력하는데만 1~2일이 걸린다..

저걸 출력하면

이렇게 나오는데 서포터를 모두 제거해준다. 근데 서포터를 제거할 때 무조건 동그라미 친 부분 쪽의 너트 구멍 사이에 서포터를 넣었을 때는 무조건 깨끗하게 제거해야한다. 아니면 나중에 너트가 안들어가게 되는데.. 또 제거할 때 잘 못 제거하면 너트가 헐겁게 들어가서 나중에 조이거나 풀 때 안풀리거나 꽉 조여지지 않는다..

그래서 한번 더 출력하기도 했는데.. 1일이 걸려서 출력되니.. 너무 시간이..

 

암튼 모든 서포터를 제거하고

35 * 47 * 7 (6807) 베어링을 박는다. 베어링을 박을 때 안들어간다고 망치로 때리면.. 박살난다.. 그럼으로 사포로 깍거나 3D 프린터를 캘리브레이션 한 후에 박는 것이 중요하다.. 난 적당히 사포로 갈고 망치로 때려 넣었다..

 

그리고 이런 부품이 있는데 이 부품에는 40 * 60 * 13 (51108) 스러스트 볼 베어링을 놓는다. 그리고 이걸 아까 그 부품에 뒤집어서 끼운다.

이렇게 그리고 꾸욱 눌러서 안빠질 정도로 깊게 끼운다... 근데 조심해야할껀 항상 집에 습도가 높으면 제습기를 설치하면 좋은 것 같다.. 아니면 가만히 놔두면 중국제일 경우 다 녹슨다..

이런식으로 베어링 사이에 꽉 끼고 잘 안빠지도록 고정시킨다.

그리고 앞 뒤로 베어링을 끼운다.. 이것도 잘 갈아서 어떻게든 끼워야 된다.

그 후에 이 부품에도 똑같은 40 * 60 * 13 (51108) 스러스트 볼 베어링을 놓고 뒤집어서 아까 끼웠던 부품의 반대편에 맞춰서 끼운다. 그리고 또 눌러서 잘 끼운다. 다만 끼울 때는 아래 사진처럼 고정하기 위해 나사를 끼우는데 정확히 구멍에 들어가도록 끼워야 한다. 좀 더 잘 끼울려면 미리 나사를 한쪽에 넣고 반대쪽에 들어가게 한 상태로 끼우는 것이 쉬웠다.

이런식으로.. 이렇게 끼운 후에는 M4 60하고 M4 락너트로 단단하게 고정시킨다. 만약에 출력할 때 내부 채움을 많이 했다면 완전 단단히 조여도 괜찮긴 하겠지만.. 별로 안넣었다면 꽉 조이면 우두둑 하는 소리가 들리긴 할꺼다.. 그래도 이 부분은 확실하게 잠가야 한다.. 약간의 우둑 소리는 나도 아마 괜찮을꺼다.. 여기가 중요한 이유는 저쪽이 약하면 다 만들었을 때 상체가 엄청 무거워서 잘 안끼워서 쉽게 기울어지거나 하면 금방 박살날 수 있다. (내가 그래서 다시 출력했었다..)

 

그 후엔 300mm * 6mm의 GT2 벨트를 서로 고정시킨다. 

그 후에 NEMA 17 (38.5mm) 모터를 M3 나사로 잘 고정시켜주고 (아마 8mm였던 것 같은데..) GT2 타이밍 풀리 6mm를 모터 샤프트에 고정시킨 후

200mm * 6mm의 GT2 벨트로 사진처럼 타이밍 풀리와 기어를 연결시켜 사진처럼 완성시킨다. 그 후에 M8 45 나사와 M8 락너트로 고정시켜준다. 사진엔 없지만 고정시킬 땐 베어링 사이사이에 M8 와셔를 같이 넣고 고정시킨다. 아니면 베어링에 무리를 줄 수 있다. 그리고 잘 안돌아갈 수도 있다..

 

그리고 이렇게 생긴 스위치로 선을 몇번이나 꼬아서 전기가 잘 통하게 선 색깔에 맞춰 연결시켜주고 수축튜브로 잘 마감시킨다. 만약에 잘 꼬아서 하지 않으면 대충 연결되어서 나중에 다시 빼서 나처럼 다시 제대로 감고 끼우게 될 수 있다.. 그리고 드릴로 저 스위치 구멍에 3mm 비트로 구멍을 뚫는다. 왜냐면.. 안뚫으면 저 스위치의 경우 안들어간다.. 2.5mm 정도 되는 것 같다.. 선의 길이는 대충 대보고 잘라서 하는게 좋다.

 

그 후 이런식으로 고정한다. 근데 여기에서 한쪽은 너트가 없는 이유는 저기 위쪽 부분과 걸리게 된다.. 그래서 그 부분만 빼고 잘 끼워준다. 그러면 잘 고정되게 되는데.. 문제는 특이하게 나중에 과도하게 돌아갈려고 하면 스위치 부분이 휘어져서 망가지게 된다.. 그러니 만약 할 수 있다면 쉽게 뺐다 끼웠다 하는 구조로 하는게 좋을 수도 있다. 수시로 계속 휘는 경우가 있다..

 

아래에는 이렇게 고정하면 되고.. 만약 된다면 한쪽은 너트로 고정을 안시켰기 때문에 찰흙이나 이런걸로 고정시키는 것도 좋다. 그 후에는 오른쪽에 있는 GT2 타이밍 풀리로 잘 고정해서 벨트의 텐션을 조절시킬 수 있도록 잘 끼워준다. (사진은 없다..)

 

그렇게 해서 하단부분은 완성을 했다. 다른 부품들은 테스트로 끼워본거..

반응형

+ Recent posts