forked from xiaozhi/xiaozhi-esp32
* otto v1.4.0 MCP 1.使用MCP协议控制机器人 2.gif继承lcdDisplay,避免修改lcdDisplay * otto v1.4.1 gif as components gif as components * electronBot v1.1.0 mcp 1.增加electronBot支持 2.mcp协议 3.gif 作为组件 4.display子类 * 规范代码 1.规范代码 2.修复切换主题死机bug * fix(ota): 修复 ottoRobot和electronBot OTA 升级崩溃问题 bug * 1.增加robot舵机初始位置校准 2.fix(mcp_sever) 超出范围异常捕获类型 bug * refactor: Update Electron and Otto emoji display implementations - Removed GIF selection from Kconfig for Electron and Otto boards. - Updated Electron and Otto bot versions to 2.0.4 in their respective config files. - Refactored emoji display classes to utilize EmojiCollection for managing emojis. - Enhanced chat label setup and status display functionality in both classes. - Cleaned up unused code and improved initialization logging for emoji displays. * Rename OTTO_ICON_FONT.c to otto_icon_font.c * Rename OTTO_ICON_FONT.c to otto_icon_font.c * refactor: Update Otto emoji display configurations and functionalities - Changed chat label text mode to circular scrolling for both Otto and Electron emoji displays. - Bumped Otto robot version to 2.0.5 in the configuration file. - Added new actions for Otto robot including Sit, WhirlwindLeg, Fitness, Greeting, Shy, RadioCalisthenics, MagicCircle, and Showcase. - Enhanced servo sequence handling and added support for executing custom servo sequences. - Improved logging and error handling for servo sequence execution. * refactor: Update chat label long mode for Electron and Otto emoji displays - Changed chat label text mode from wrap to circular scrolling for both Electron and Otto emoji displays. - Improved consistency in chat label setup across both implementations. * Update Otto robot README with new actions and parameters
162 lines
4.2 KiB
C++
162 lines
4.2 KiB
C++
//--------------------------------------------------------------
|
|
//-- Oscillator.pde
|
|
//-- Generate sinusoidal oscillations in the servos
|
|
//--------------------------------------------------------------
|
|
//-- (c) Juan Gonzalez-Gomez (Obijuan), Dec 2011
|
|
//-- (c) txp666 for esp32, 202503
|
|
//-- GPL license
|
|
//--------------------------------------------------------------
|
|
#include "oscillator.h"
|
|
|
|
#include <driver/ledc.h>
|
|
#include <esp_timer.h>
|
|
|
|
#include <algorithm>
|
|
#include <cmath>
|
|
|
|
static const char* TAG = "Oscillator";
|
|
|
|
extern unsigned long IRAM_ATTR millis();
|
|
|
|
static ledc_channel_t next_free_channel = LEDC_CHANNEL_0;
|
|
|
|
Oscillator::Oscillator(int trim) {
|
|
trim_ = trim;
|
|
diff_limit_ = 0;
|
|
is_attached_ = false;
|
|
|
|
sampling_period_ = 30;
|
|
period_ = 2000;
|
|
number_samples_ = period_ / sampling_period_;
|
|
inc_ = 2 * M_PI / number_samples_;
|
|
|
|
amplitude_ = 45;
|
|
phase_ = 0;
|
|
phase0_ = 0;
|
|
offset_ = 0;
|
|
stop_ = false;
|
|
rev_ = false;
|
|
|
|
pos_ = 90;
|
|
previous_millis_ = 0;
|
|
}
|
|
|
|
Oscillator::~Oscillator() {
|
|
Detach();
|
|
}
|
|
|
|
uint32_t Oscillator::AngleToCompare(int angle) {
|
|
return (angle - SERVO_MIN_DEGREE) * (SERVO_MAX_PULSEWIDTH_US - SERVO_MIN_PULSEWIDTH_US) /
|
|
(SERVO_MAX_DEGREE - SERVO_MIN_DEGREE) +
|
|
SERVO_MIN_PULSEWIDTH_US;
|
|
}
|
|
|
|
bool Oscillator::NextSample() {
|
|
current_millis_ = millis();
|
|
|
|
if (current_millis_ - previous_millis_ > sampling_period_) {
|
|
previous_millis_ = current_millis_;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void Oscillator::Attach(int pin, bool rev) {
|
|
if (is_attached_) {
|
|
Detach();
|
|
}
|
|
|
|
pin_ = pin;
|
|
rev_ = rev;
|
|
|
|
ledc_timer_config_t ledc_timer = {.speed_mode = LEDC_LOW_SPEED_MODE,
|
|
.duty_resolution = LEDC_TIMER_13_BIT,
|
|
.timer_num = LEDC_TIMER_1,
|
|
.freq_hz = 50,
|
|
.clk_cfg = LEDC_AUTO_CLK};
|
|
ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer));
|
|
|
|
static int last_channel = 0;
|
|
last_channel = (last_channel + 1) % 7 + 1;
|
|
ledc_channel_ = (ledc_channel_t)last_channel;
|
|
|
|
ledc_channel_config_t ledc_channel = {.gpio_num = pin_,
|
|
.speed_mode = LEDC_LOW_SPEED_MODE,
|
|
.channel = ledc_channel_,
|
|
.intr_type = LEDC_INTR_DISABLE,
|
|
.timer_sel = LEDC_TIMER_1,
|
|
.duty = 0,
|
|
.hpoint = 0};
|
|
ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel));
|
|
|
|
ledc_speed_mode_ = LEDC_LOW_SPEED_MODE;
|
|
|
|
// pos_ = 90;
|
|
// Write(pos_);
|
|
previous_servo_command_millis_ = millis();
|
|
|
|
is_attached_ = true;
|
|
}
|
|
|
|
void Oscillator::Detach() {
|
|
if (!is_attached_)
|
|
return;
|
|
|
|
ESP_ERROR_CHECK(ledc_stop(ledc_speed_mode_, ledc_channel_, 0));
|
|
|
|
is_attached_ = false;
|
|
}
|
|
|
|
void Oscillator::SetT(unsigned int T) {
|
|
period_ = T;
|
|
|
|
number_samples_ = period_ / sampling_period_;
|
|
inc_ = 2 * M_PI / number_samples_;
|
|
}
|
|
|
|
void Oscillator::SetPosition(int position) {
|
|
Write(position);
|
|
}
|
|
|
|
void Oscillator::Refresh() {
|
|
if (NextSample()) {
|
|
if (!stop_) {
|
|
int pos = std::round(amplitude_ * std::sin(phase_ + phase0_) + offset_);
|
|
if (rev_)
|
|
pos = -pos;
|
|
Write(pos + 90);
|
|
}
|
|
|
|
phase_ = phase_ + inc_;
|
|
}
|
|
}
|
|
|
|
void Oscillator::Write(int position) {
|
|
if (!is_attached_)
|
|
return;
|
|
|
|
long currentMillis = millis();
|
|
if (diff_limit_ > 0) {
|
|
int limit = std::max(
|
|
1, (((int)(currentMillis - previous_servo_command_millis_)) * diff_limit_) / 1000);
|
|
if (abs(position - pos_) > limit) {
|
|
pos_ += position < pos_ ? -limit : limit;
|
|
} else {
|
|
pos_ = position;
|
|
}
|
|
} else {
|
|
pos_ = position;
|
|
}
|
|
previous_servo_command_millis_ = currentMillis;
|
|
|
|
int angle = pos_ + trim_;
|
|
|
|
angle = std::min(std::max(angle, 0), 180);
|
|
|
|
uint32_t duty = (uint32_t)(((angle / 180.0) * 2.0 + 0.5) * 8191 / 20.0);
|
|
|
|
ESP_ERROR_CHECK(ledc_set_duty(ledc_speed_mode_, ledc_channel_, duty));
|
|
ESP_ERROR_CHECK(ledc_update_duty(ledc_speed_mode_, ledc_channel_));
|
|
}
|