// Наблюдение в MyRobotica включается сборщиком; обычный Arduino работает без библиотеки. #include #if defined(ROBOT_TELEMETRY_BUILD_ID) #include robot_telemetry::TelemetryStream courseTelemetry; #endif // Каркас П-регулятора. Требования к программе — в тексте урока, шаг за шагом. const int LEFT_SENSOR_PIN = A4; const int RIGHT_SENSOR_PIN = A5; // Измерения белого и чёрного из журнала (урок 3.1). const int LEFT_WHITE = 0; const int LEFT_BLACK = 0; const int RIGHT_WHITE = 0; const int RIGHT_BLACK = 0; const int LEFT_DIR_PIN = 7; const int LEFT_SPEED_PIN = 6; const int RIGHT_DIR_PIN = 4; const int RIGHT_SPEED_PIN = 5; const int FORWARD = HIGH; void drive(int leftDir, int leftSpeed, int rightDir, int rightSpeed) { digitalWrite(LEFT_DIR_PIN, leftDir); digitalWrite(RIGHT_DIR_PIN, rightDir); analogWrite(LEFT_SPEED_PIN, leftSpeed); analogWrite(RIGHT_SPEED_PIN, rightSpeed); } // Требование 1: шкала «чёрное — 0, белое — 100». int level(int value, int white, int black) { return 0; } void setup() { courseTelemetryBegin(); pinMode(LEFT_DIR_PIN, OUTPUT); pinMode(LEFT_SPEED_PIN, OUTPUT); pinMode(RIGHT_DIR_PIN, OUTPUT); pinMode(RIGHT_SPEED_PIN, OUTPUT); drive(FORWARD, 0, FORWARD, 0); // Без измерений робот не поедет. Эту защиту не удаляй. if (LEFT_WHITE == LEFT_BLACK || RIGHT_WHITE == RIGHT_BLACK) { while (true) { courseTelemetryPoll(); } } courseWait(2000); } void loop() { float observedError = NAN; float observedOutput = NAN; // Требования 2 и 3: ошибка, поправка и скорости колёс. // Для графиков сохрани свои результаты в observedError и observedOutput. drive(FORWARD, 0, FORWARD, 0); courseTelemetryReport(analogRead(LEFT_SENSOR_PIN), analogRead(RIGHT_SENSOR_PIN), observedError, observedOutput); } // ===== Готовое: передача наблюдений — не меняй ===== void courseTelemetryBegin() { #if defined(ROBOT_TELEMETRY_BUILD_ID) using namespace robot_telemetry::wire; courseTelemetry.begin((1UL << Line0) | (1UL << Line1) | (1UL << LineError) | (1UL << ControlOutput)); #else Serial.begin(9600); #endif } void courseTelemetryPoll() { #if defined(ROBOT_TELEMETRY_BUILD_ID) courseTelemetry.update(); #endif } // NAN означает «ещё не вычислено», а не нулевую ошибку или поправку. void courseTelemetryReport(int leftRaw, int rightRaw, float error, float output) { #if defined(ROBOT_TELEMETRY_BUILD_ID) using namespace robot_telemetry::wire; courseTelemetry.setUnsigned(Line0, leftRaw); courseTelemetry.setUnsigned(Line1, rightRaw); if (isnan(error)) courseTelemetry.setMissing(LineError); else courseTelemetry.setFloat(LineError, error); if (isnan(output)) courseTelemetry.setMissing(ControlOutput); else courseTelemetry.setFloat(ControlOutput, output); courseTelemetry.update(); #endif } void courseWait(unsigned long durationMs) { unsigned long started = millis(); while (millis() - started < durationMs) { courseTelemetryPoll(); delay(1); } }