0

所以我尝试为我的步进电机的运动实现一个 S 曲线;但是,我觉得这对于我希望步进电机做的简单事情来说太复杂了:平滑运动。不必一眨眼就从a到b,顺手就行。此外,该函数会超调大量步数(pos_err 几乎总是步数的 40%)。

void stepper_t::step(int32_t steps, direction dir)
{

    float32_t pulse_delay;      /* Stepper pulse delay [microsec] */

    int8_t count = 0;           /* Count the number of pulses */
    int32_t pos_err = 0;        /* Error in position */

    int16_t speed = 3200;       /* Steady state velocity [pulse/s] */

    int8_t var = 0;

    int32_t move_time = (steps / (speed / 1000000));                    /* Total time moving */
    int32_t accel_time = move_time < 30000 ? (move_time / 2) : 30000;   /* Acceleration time [microsec] */
    int32_t decel_time = move_time < 30000 ? (move_time / 2) : 30000;   /* Deceleration time [microsec] */
    int32_t constant_speed = move_time - (accel_time + decel_time);     /* Time during constant velocity [microsec] */

    int32_t curr_time = decel_time / 30; /* Current time     [microsec] 
                                            You need to seed the initial time 
                                            with something > 0 so you don't 
                                            calculate too long of a delay */

    this->set_direction(dir);

    while (var < 1) {         
        if (curr_time < accel_time) {  
            /* Acceleration */                                     
            pulse_delay = ((float32_t) accel_time / (2.f * ((float32_t) speed / 1000000.f) * (float32_t) curr_time));
        } else if ((curr_time >= accel_time) && (curr_time < (accel_time + constant_speed))) {      
            /* Constant velocity */
            pulse_delay = (1.f / (2.f * ((float32_t) speed / 1000000.f)));
        } else if ((curr_time >= (accel_time + constant_speed)) && (curr_time < (accel_time + constant_speed + decel_time))) {    
            /* Deceleration */
            pulse_delay = (1.f / (2.f * (((float32_t) speed / 1000000.f) - ((float32_t) speed / (1000000.f * (float32_t) decel_time)) * ((float32_t) curr_time - (float32_t) accel_time - (float32_t) constant_speed))));
        }

        /* Time is incremented by pulse delay twice due to the pin going
        high, then low, delaying twice */
        curr_time = curr_time + (int32_t) (float32_t) (2.f * pulse_delay);

        /* Send pulse with calculated delay */
        Chip_GPIO_SetPinState(LPC_GPIO_PORT, this->GPIO_step_port, this->GPIO_step_pin, true);
        OS_Delayus((OS_U16) pulse_delay);
        Chip_GPIO_SetPinState(LPC_GPIO_PORT, this->GPIO_step_port, this->GPIO_step_pin, false);
        OS_Delayus((OS_U16) pulse_delay);

        count++;

        /* Correct for any position error due to rounding */
        if (curr_time > (accel_time + constant_speed + decel_time)) {
            pos_err = steps - count;

            if (pos_err < 0) {
                pos_err = -1 * pos_err;

                if (dir == OUTWARD) {
                    this->set_direction(INWARD);
                } else {
                    this->set_direction(OUTWARD);
                }
            }

            for (; pos_err > 0; pos_err--) {
                Chip_GPIO_SetPinState(LPC_GPIO_PORT, this->GPIO_step_port, this->GPIO_step_pin, true);
                OS_Delayus((OS_U16) pulse_delay);
                Chip_GPIO_SetPinState(LPC_GPIO_PORT, this->GPIO_step_port, this->GPIO_step_pin, false);
                OS_Delayus((OS_U16) pulse_delay);
            }

            count = 0;
            curr_time = decel_time / 9;
            var++;
        }
    }
}

为什么我不能像这样使用余弦来计算两者之间的延迟?

void step2(int32_t steps) {

    int8_t count = 0;
    float32_t delay;

    while (count < steps) {
        delay = (cos ( (PI * 2 * count)/steps ) + 1) * 5000 + 10000;
        Chip_GPIO_SetPinState(LPC_GPIO_PORT, this->GPIO_step_port, this->GPIO_step_pin, true);
        OS_Delayus((OS_U16) delay);
        Chip_GPIO_SetPinState(LPC_GPIO_PORT, this->GPIO_step_port, this->GPIO_step_pin, false);
        OS_Delayus((OS_U16) delay);
        count++;
    }
}
4

0 回答 0