// // Created by Administrator on 2025/12/24. // #include "erpc/service/include/servo_service_impl.h" #include #include "common/type/common_type.h" const std::vector ServoServiceImpl::kServoCfg = { {"eye_l_up", "pwm1", 1, 20000000, 500000, 2500000, -0.5f * PI, 0.5f * PI, 0.0f}, // {"eye_r_up", "pwm1", 2, 20000000, 500000, 2500000, 0.0f, kPi, 0.5f * kPi}, // ... }; ServoServiceImpl::ServoServiceImpl() : manager_(kServoCfg), init_err_(RT_EOK), mode_(MotionMode::Immediate), mutex_(RT_NULL) { mutex_ = rt_mutex_create("sv_svc", RT_IPC_FLAG_PRIO); if (!mutex_) { init_err_ = -RT_ENOMEM; rt_kprintf("[ServoService][E] mutex create FAILED, err=%d\n", (int)init_err_); return; } init_err_ = manager_.init(true, true); if (init_err_ != RT_EOK) { rt_kprintf("[ServoService][E] init FAILED, err=%d\n", (int)init_err_); return; } manager_.setUpdatePeriodMs(1); for (const auto& cfg : kServoCfg) { ServoControl* servo = manager_.get(cfg.servo_id); if (!servo) { init_err_ = -RT_ENOSYS; rt_kprintf("[ServoService][E] missing servo control, id=%s\n", cfg.servo_id.c_str()); return; } servo->setConstraints( 3.14, 31.4, 31.4); } init_err_ = manager_.start(); if (init_err_ != RT_EOK) { rt_kprintf("[ServoService][E] manager start FAILED, err=%d\n", (int)init_err_); } } ServoServiceImpl::~ServoServiceImpl() { if (mutex_) { rt_mutex_delete(mutex_); mutex_ = RT_NULL; } } bool ServoServiceImpl::setConstraints(const char* id, float max_velocity_rad, float max_acceleration_rad, float max_jerk_rad) { if (init_err_ != RT_EOK) { rt_kprintf("[ServoService][E] setConstraints: service not ready, init_err=%d\n", (int)init_err_); return false; } if (!id) { rt_kprintf("[ServoService][E] setConstraints: id is null\n"); return false; } if (max_velocity_rad <= 0.0f || max_acceleration_rad <= 0.0f || max_jerk_rad <= 0.0f) { rt_kprintf("[ServoService][E] setConstraints: invalid constraints, id=%s v=%.4f a=%.4f j=%.4f\n", id, (double)max_velocity_rad, (double)max_acceleration_rad, (double)max_jerk_rad); return false; } ServoControl* servo = manager_.get(std::string(id)); if (!servo) { rt_kprintf("[ServoService][E] setConstraints: servo not found, id=%s\n", id); return false; } servo->setConstraints(max_velocity_rad, max_acceleration_rad, max_jerk_rad); rt_kprintf("[ServoService] setConstraints: id=%s v=%.4f a=%.4f j=%.4f\n", id, (double)max_velocity_rad, (double)max_acceleration_rad, (double)max_jerk_rad); return true; } bool ServoServiceImpl::setMode(RpcMotionMode mode) { if (init_err_ != RT_EOK) { rt_kprintf("[ServoService][E] setMode: service not ready, init_err=%d\n", (int)init_err_); return false; } if (!mutex_) { rt_kprintf("[ServoService][E] setMode: mutex is null\n"); return false; } MotionMode motion_mode; switch (mode) { case RpcMotionModeImmediate: motion_mode = MotionMode::Immediate; break; case RpcMotionModeSCurve: motion_mode = MotionMode::SCurve; break; default: rt_kprintf("[ServoService][E] setMode: invalid mode=%d\n", (int)mode); return false; } rt_mutex_take(mutex_, RT_WAITING_FOREVER); mode_ = motion_mode; rt_mutex_release(mutex_); rt_kprintf("[ServoService] setMode: mode=%d\n", (int)mode); return true; } bool ServoServiceImpl::setUpdatePeriodMs(uint32_t ms) { if (init_err_ != RT_EOK) { rt_kprintf("[ServoService][E] setUpdatePeriodMs: service not ready, init_err=%d\n", (int)init_err_); return false; } manager_.setUpdatePeriodMs(ms); manager_.wake(); rt_kprintf("[ServoService] setUpdatePeriodMs: ms=%u\n", (unsigned)ms); return true; } int32_t ServoServiceImpl::move(const list_ServoCmd_1_t* cmds) { if (init_err_ != RT_EOK) { rt_kprintf("[ServoService][E] move: service not ready, init_err=%d\n", (int)init_err_); return init_err_; } if (!cmds) { rt_kprintf("[ServoService][E] move: cmds is null\n"); return -RT_EINVAL; } if (!cmds->elements || cmds->elementsCount == 0) { rt_kprintf("[ServoService][E] move: empty list (elements=%p, count=%d)\n", cmds->elements, (int)cmds->elementsCount); return -RT_EINVAL; } if (!mutex_) { rt_kprintf("[ServoService][E] move: mutex is null\n"); return -RT_ENOMEM; } rt_mutex_take(mutex_, RT_WAITING_FOREVER); const MotionMode motion_mode = mode_; rt_mutex_release(mutex_); for (uint32_t i = 0; i < cmds->elementsCount; ++i) { const char* id = cmds->elements[i].id; if (!id) { rt_kprintf("[ServoService][E] move: cmds[%d].id is null\n", (int)i); return -RT_EINVAL; } ServoControl* servo = manager_.get(std::string(id)); if (!servo) { rt_kprintf("[ServoService][E] move: servo not found, id=%s\n", id); return -RT_ENOSYS; } const rt_err_t err = servo->move(cmds->elements[i].angle_rad, motion_mode); if (err != RT_EOK) { rt_kprintf("[ServoService][E] move: move failed, id=%s angle=%.4f mode=%d err=%d\n", id, (double)cmds->elements[i].angle_rad, (int)motion_mode, (int)err); return err; } } if (motion_mode == MotionMode::SCurve) { manager_.wake(); } return RT_EOK; } int32_t ServoServiceImpl::moveJ(const list_float_1_t* angles_rad) { if (init_err_ != RT_EOK) { rt_kprintf("[ServoService][E] moveJ: service not ready, init_err=%d\n", (int)init_err_); return init_err_; } if (!angles_rad) { rt_kprintf("[ServoService][E] moveJ: angles_rad is null\n"); return -RT_EINVAL; } if (!angles_rad->elements || angles_rad->elementsCount == 0) { rt_kprintf("[ServoService][E] moveJ: empty list (elements=%p, count=%d)\n", angles_rad->elements, (int)angles_rad->elementsCount); return -RT_EINVAL; } const size_t need = kServoCfg.size(); const size_t got = (size_t)angles_rad->elementsCount; if (got != need) { rt_kprintf("[ServoService][E] moveJ: invalid angles count, need=%d got=%d\n", (int)need, (int)got); return -RT_EINVAL; } if (!mutex_) { rt_kprintf("[ServoService][E] moveJ: mutex is null\n"); return -RT_ENOMEM; } rt_mutex_take(mutex_, RT_WAITING_FOREVER); const MotionMode motion_mode = mode_; rt_mutex_release(mutex_); for (size_t i = 0; i < need; ++i) { ServoControl* servo = manager_.get(kServoCfg[i].servo_id); if (!servo) { rt_kprintf("[ServoService][E] moveJ: servo not found, id=%s\n", kServoCfg[i].servo_id.c_str()); return -RT_ENOSYS; } const rt_err_t err = servo->move(angles_rad->elements[i], motion_mode); if (err != RT_EOK) { rt_kprintf("[ServoService][E] moveJ: move failed, id=%s angle=%.4f mode=%d err=%d\n", kServoCfg[i].servo_id.c_str(), (double)angles_rad->elements[i], (int)motion_mode, (int)err); return err; } } if (motion_mode == MotionMode::SCurve) { manager_.wake(); } return RT_EOK; }