티스토리 뷰

모터 회전 구현하기

-Processing-



목표


Processing에서 GUI 형태로 매개변수(게인)값을 조정해서 아두이노로 시리얼 통신을 통해 값을 전달해 주는 코드 작성하기







소스코드



import controlP5.*;
import processing.serial.*;

ControlP5 cp5;
Serial comPort;

void setup(){
  size(700, 360);
  noStroke();
  
  cp5 = new ControlP5(this);
  
  cp5.addTextlabel("", "Drone PID Tunning")
  .setPosition(200, 10)
  .setColorValue(0xffffff00)
  .setFont(createFont("Lucida Sans", 30))
  ;
  
  cp5.addSlider("throttle")
  .setRange(0, 255)
  .setScrollSensitivity(5.0 * 10 / 255)
  .setPosition(20, 60)
  .setSize(600, 19)
  .setValue(0)
  ;
  
  cp5.addSlider("roll_kp")
  .setRange(0, 10)
  .setScrollSensitivity(0.2 * 10 / 10)
  .setPosition(20, 100)
  .setSize(600, 19)
  .setValue(1)
  ;
  
  cp5.addSlider("roll_ki")
  .setRange(0, 0.25)
  .setScrollSensitivity(0.005 * 10 / 0.25)
  .setPosition(20, 120)
  .setSize(600, 19)
  .setValue(0)
  ;
  
  cp5.addSlider("roll_kd")
  .setRange(0, 0.6)
  .setScrollSensitivity(0.1 * 10 / 0.6)
  .setPosition(20, 140)
  .setSize(600, 19)
  .setValue(0)
  ;
  
  ////////PITCH///////
  cp5.addSlider("pitch_kp")
  .setRange(0, 10)
  .setScrollSensitivity(0.2 * 10 / 10)
  .setPosition(20, 180)
  .setSize(600, 19)
  .setValue(1)
  ;
  
  cp5.addSlider("pitch_ki")
  .setRange(0, 0.25)
  .setScrollSensitivity(0.005 * 10 / 0.25)
  .setPosition(20, 200)
  .setSize(600, 19)
  .setValue(0)
  ;
  
  cp5.addSlider("pitch_kd")
  .setRange(0, 0.6)
  .setScrollSensitivity(0.1 * 10 / 0.6)
  .setPosition(20, 220)
  .setSize(600, 19)
  .setValue(0)
  ;
  
  ///////YAW///////
  cp5.addSlider("yaw_kp")
  .setRange(0, 10)
  .setScrollSensitivity(0.2 * 10 / 10)
  .setPosition(20, 260)
  .setSize(600, 19)
  .setValue(1)
  ;
  
  cp5.addSlider("yaw_ki")
  .setRange(0, 0.25)
  .setScrollSensitivity(0.005 * 10 / 0.25)
  .setPosition(20, 280)
  .setSize(600, 19)
  .setValue(0)
  ;
  
  cp5.addSlider("yaw_kd")
  .setRange(0, 0.6)
  .setScrollSensitivity(0.1 * 10 / 0.6)
  .setPosition(20, 300)
  .setSize(600, 19)
  .setValue(0)
  ;
  
  println((Object[])Serial.list());
  String portName = Serial.list()[0];
  comPort = new Serial(this, portName, 115200);
  
  comPort.write('T'); comPort.write(0);
  comPort.write('a'); comPort.write(5);
  comPort.write('b'); comPort.write(0);
  comPort.write('c'); comPort.write(0);
  comPort.write('d'); comPort.write(5);
  comPort.write('e'); comPort.write(0);
  comPort.write('f'); comPort.write(0);
  comPort.write('g'); comPort.write(5);
  comPort.write('h'); comPort.write(0);
  comPort.write('i'); comPort.write(0);
}

void draw(){
  background(0);
}

public void throttle(float speed){
  println("throttle : " + speed);
  comPort.write('T');
  comPort.write((int)speed);
}

public void roll_kp(float kp)
{
  println("roll kp : " + kp);
  comPort.write('a');
  comPort.write((int)((kp + 0.01) / 0.2));
}
 
public void roll_ki(float ki) 
{  
  println("roll ki : " + ki);
  comPort.write('b');
  comPort.write((int)(ki/0.005));
}
 
public void roll_kd(float kd) 
{  
  println("roll kd : " + kd);
  comPort.write('c');
  comPort.write((int)((kd+0.01)/0.1));
}
 
public void pitch_kp(float kp) 
{
  println("pitch kp : " + kp);
  comPort.write('d');
  comPort.write((int)((kp+0.01)/0.2));
}
 
public void pitch_ki(float ki) 
{  
  println("pitch ki : " + ki);
  comPort.write('e');
  comPort.write((int)(ki/0.005));
}
 
public void pitch_kd(float kd) 
{  
  println("pitch kd : " + kd);
  comPort.write('f');
  comPort.write((int)((kd+0.01)/0.1));
}
 
public void yaw_kp(float kp) 
{
  println("yaw kp : " + kp);
  comPort.write('g');
  comPort.write((int)((kp+0.01)/0.2));
}
 
public void yaw_ki(float ki) 
{  
  println("yaw ki : " + ki);
  comPort.write('h');
  comPort.write((int)(ki/0.005));
}
 
public void yaw_kd(float kd) 
{  
  println("yaw kd : " + kd);
  comPort.write('i');
  comPort.write((int)((kd+0.01)/0.1));
}

다운로드 파일

sketch_160916a.pde






이전에 다 설명했던 내용들이여서 자세하게는 설명을 안하도록 하겠습니다.


일단!


Q. 모든 처리하는 내용들을 draw() 함수에 선언 안하고 setup() 함수에 선언을 했을까?


-> GUI 상에서 스크롤을 증가 감소 시킬때 마다 프로세싱 프로그램은 실행이 되는 것 입니다. 따라서 매번 스크롤을 변경할때마다 setup() 함수가 호출이 되게 됩니다. 그래서 setup() 함수에 선언을 해준 것 입니다.



Q. 시리얼 통신으로 각 알파벳을 보내는데 이건 왜 보내는건가요?


setup() 함수에서 선언된 구문




외부에서 선언된 함수



위 두개 내용을 보면 setup() 함수에서는 addSlider라고  "throttle" 입니다. 이건 GUI상에서 직접적으로 글자가 보여지는 동시에 throttle 함수를 호출하는 것 입니다. 따라서 public로 선언된 곳을 보시면 comPort.write('T') 시리얼 통신으로 알파벳 T라는 글자를 보내고 int형으로 speed 값도 같이 보내겠다 라는 뜻 입니다. 여기서 speed는 float형으로 받고 있는데 addSlider에서 .setValue값이 speed 값으로 주어지는 것 입니다.


이것에 대한 내용을 콜백함수 라고 부르는데 이전 포스팅에서 자세하게 설명을 하였으니 참고하면 좋을거 같습니다.






따라서 GUI 상에서 매개변수와 throttle 값을 변경함에 따라서 모터의 속도가 달라지게 됩니다.

Comments