Arduino als Chassismanagement

Der Arduino wird in diesem Projekt verwendet um Lenkwinkel / Geschwindigkeit und Fahrtrichtung des WebControlledCar ein zu regeln. Die Regelung könnte durchaus auch über den ohnehin in dem Projekt vorhandenen Raspberry Pi ausgeführt werden, hier zeigt sich jedoch je nach Betriebssystemauslastung ein mehr oder weniger ausgeprägtes Zittern von Servo und DC-Motor Regelung. Der Arduino erfüllt die Aufgabe hier naturgemäß deutlich besser.

 

Programmierung des Arduino

Der Arduino liesst seine Steuerbefehle über die serielle Schnitstelle vom Raspberry Pi ein.

Die Daten werden vom Raspberry Pi in der Form MOVXMSPYYYMSTZZZ ausgegeben, wobei X die Fahrtrichtung überträgt, YYY die Geschwindigkeit und ZZZ den Lenkwinkel.

Dem Arduino steht ein RC-Servo zur Einstellung des Lenkwinkels sowie ein L298N zur Steuerung des DC-Motors zur Verfügung.

Anforderung an die Chassismanagement Software ist ein sanftes Einregeln der Solllgrößen. D.h. es sollen keine abrupten Fahrtrichtungswechsel statt finden. Bei Fahrtrichtungswechsel soll der Arduino das Fahrzeug sanft abbremsen und anschließend in die Gegenrichtung beschleunigen an statt einfach nur die Polariät der Ausgangsspannung am L298N  zu drehen. Hierfür wird im Quellcode zwischen Soll- und Ist-Größen unterschieden und eine kleine StateMachine steuert den Übergang der Fahrtrichtung in eine andere.


#include <Servo.h>
//__OUT=PWM-Ausgang__actual=IST-Wert__target=SOLL-Wert
//__0=Stilstand___1=Vorwärts___2=Rückwärts
int move_state_target = 0;
int move_state_actual = 0;
int move_state_out = 0;
int move_speed_target = 0;
int move_speed_actual = 0;
int move_speed_out = 0;
int steering_target = 90;
int steering_actual = 90;
int steering_out = 90;
int delay_loop = 200;
Servo steering_servo;  
String serial_read = "";

const int backward_pin1 = 11;
const int backward_pin2 = 3;
const int forward_pin1 = 6;
const int forward_pin2 = 5;
const int move_speed_max = 150;
const int move_speed_min = 0;
const int steering_max = 150;
const int steering_min = 30;

void setup() {
  Serial.begin(9600);
  steering_servo.attach(9);  // attaches the servo on pin 9 to the servo object
  pinMode(backward_pin1, OUTPUT);
  pinMode(backward_pin2, OUTPUT);
  pinMode(forward_pin1, OUTPUT);
  pinMode(forward_pin2, OUTPUT);
}

void forward() {
  analogWrite(forward_pin1,move_speed_out);
  analogWrite(forward_pin2,move_speed_out);
  analogWrite(backward_pin1,0);
  analogWrite(backward_pin2,0);
  Serial.println("Vorwärts #" + String(move_speed_out));
  move_speed_actual = move_speed_out;
}

void backward() {
  analogWrite(forward_pin1,0);
  analogWrite(forward_pin2,0);
  analogWrite(backward_pin1,move_speed_out);
  analogWrite(backward_pin2,move_speed_out);
  Serial.println("Rückwärts #" + String(move_speed_out));
  move_speed_actual = move_speed_out;
}

void halt() {
  analogWrite(forward_pin1,0);
  analogWrite(forward_pin2,0);
  analogWrite(backward_pin1,0);
  analogWrite(backward_pin2,0);
  Serial.println("Stilstand #" + String(move_speed_out));
  move_speed_actual = move_speed_out;
}

void unknown() {
  analogWrite(forward_pin1,0);
  analogWrite(forward_pin2,0);
  analogWrite(backward_pin1,0);
  analogWrite(backward_pin2,0);
  Serial.println("Zustand unbekannt:" + String(move_state_target) + "#" + String(move_speed_out));
  move_state_target = 0;
  move_state_actual = 0;
  move_state_out = 0;
  move_speed_actual = 0;
  move_speed_target = 0;
  move_speed_out = 0;
}

void movement() {
  //move_state going for a halt ==> target speed is zero
  if (move_state_target == 0) {
    move_speed_target = 0;
}

  
  //move_state_change ==> reduce speed to zero then actually change state
  if (move_state_actual != move_state_target) { 
    move_speed_out = move_speed_actual - 20;
    if (move_speed_out <= 0) {
      move_speed_out = 0;
      move_state_out = move_state_target;
    }
  }

 
  //no move state change
  else {
    if (move_speed_target >= move_speed_max) {
      move_speed_target = move_speed_max;   
    }
    if (move_speed_target <= move_speed_min) {
      move_speed_target = move_speed_min;
    }
    if (move_speed_target > move_speed_actual) {
      move_speed_out = move_speed_actual + 10;
    }
    if (move_speed_target < move_speed_actual) {
      move_speed_out = move_speed_actual - 11;
    }
  }

  if (move_state_out == 0) {
    halt();
    move_state_actual = move_state_out;
  }
  else if (move_state_out == 1) {
    forward();
    move_state_actual = move_state_out;
  }
  else if (move_state_out == 2) {
    backward();
    move_state_actual = move_state_out;
  }
  else {
    unknown();
  }
}

void steering() {
  if (steering_target >= steering_max) {
    steering_target = steering_max;
  }
  if (steering_target <= steering_min) {
    steering_target = steering_min;
  }
  
  if (steering_target > steering_actual) {
    steering_out = steering_actual + 10;
  }
  if (steering_target < steering_actual) {
    steering_out = steering_actual - 11;
  }
  steering_servo.write(steering_out);
  Serial.print("   Lenwinkel #" + String(steering_out) + "  --  ");
  steering_actual = steering_out;
}

void interpret_serial_input()
{
  //Serial has to be sent as : MST1MSP230STE160
  if (Serial.available()) {
    serial_read = Serial.readString();
    move_state_target = serial_read.substring(3,4).toInt();
    move_speed_target = serial_read.substring(7,10).toInt();
    steering_target = serial_read.substring(13,16).toInt();
    Serial.println("   Zielwerte : " + serial_read + "     ==>  " + String(move_state_target) + " -- " + String(move_speed_target) + " -- " + String(steering_target));
  }
}

void loop() {
  //Read commands from serial input : MST1MSP230STE160
  interpret_serial_input();
  //Adjust steering
  steering(); 
  //Adjust movement
  movement();
  delay(delay_loop);
}

 ---

 

Wir benutzen Cookies

Wir nutzen Cookies auf unserer Website. Einige von ihnen sind essenziell für den Betrieb der Seite, während andere uns helfen, diese Website und die Nutzererfahrung zu verbessern (Tracking Cookies). Sie können selbst entscheiden, ob Sie die Cookies zulassen möchten. Bitte beachten Sie, dass bei einer Ablehnung womöglich nicht mehr alle Funktionalitäten der Seite zur Verfügung stehen.