Execution freeze on a esp32 when recreate and delete a task too many times

Hello,
To give some context I'm programming an "autonomous" robot for a competition with an esp32 and i need to create some tasks.
I have tasks that i create only once at the start (bluetooth, odometry, serialReader,...). and i have on task for a pidController that I delete and recreate each time the robot need to move, turn,...

The execution freeze when I'm trying to create a 15th task(it needs to do at least 50).

Here's the code ( be nice i'm a web dev trying to learn how to make a robot :') )

#include "PidController.h"
#include "./odometry/Odometry.h"
#include "./bluetooth/Bluetooth.h"
#include "./motor/Motor.h"
#include "./action/Action.h"
#include <Arduino.h>

// PID ligne droite
long KpD = 5000L;
long KiD = 1000L;
long KdD = 0L;

long error = 0;
long totalErrors = 0;
long dError = 0;
long lastError = 0;

long adjustLMotor;
long adjustRMotor;

int targetSpeed = 0;

int sampleTime = 10;
unsigned long lastTime;
long adjust = 0;

unsigned long lastZeroTime = 0;

Strat strategy;
int stepIndex = 0;

float accelerationDistance = 0;
float decelerationDistance = 0;
float ACCELERATION_DISTANCE = 200;
float DECELERATION_DISTANCE = 100;

void computePidStraightLine(void *pvParameters)
{
    enableMotors();
    computeAccelerations();

    int actionsDuration = getActionsDuration(strategy.steps[stepIndex].actions, strategy.steps[stepIndex].numActions);
    launchComputeActionsTask(strategy.steps[stepIndex]);

    unsigned long timeOrigin = millis();
    unsigned long stepStartTime = millis();
    while (1)
    {
        unsigned long now = millis();
        int timeChange = (now - lastTime);

        if (timeChange >= sampleTime)
        {
            error = getTicksError();
            totalErrors += error;
            dError += error - lastError;

            adjust = (KpD * error) / 1000 + (KiD * totalErrors) / 1000 + (KdD * dError) / 1000;

            if (strategy.steps[stepIndex].type == "forward")
            {
                targetSpeed = computeTargetSpeed();
            }
            else if (strategy.steps[stepIndex].type == "backward")
            {
                targetSpeed = -computeTargetSpeed();
            }
            setMotorLeftSpeed(-targetSpeed, -adjust);
            setMotorRightSpeed(targetSpeed, -adjust);

            lastTime = now;
            lastError = error;
            // p.Plot();
            if (isDeplacementAtDestination())
            {
                stopRobot();
                if (now - stepStartTime >= actionsDuration)
                {
                    Serial.println("Stop");
                    // Go to next step
                    computeNextStep();
                    // DELETE TASK
                    vTaskDelete(NULL);
                }
            }
        }

        const TickType_t delay_ms = 1 / portTICK_PERIOD_MS;
        vTaskDelay(delay_ms);
    }
}

float computeTargetSpeed()
{

    // just some math
}

void computeAccelerations()
{
    // just some math
}

void straightLine()
{
    resetTempCounterCodeur();
    xTaskCreatePinnedToCore(computePidStraightLine, "computePidStraightLine", 2048, NULL, 2, NULL, 1);
}

void computeStrategy(Strat strat)
{
    strategy = strat;
    computeNextStep();
}

void computeNextStep()
{
    // delay(100);
    stepIndex = stepIndex + 1;
    Serial.println(stepIndex);
    if (stepIndex < strategy.numSteps)
    {
        if (strategy.steps[stepIndex].type == "forward" || strategy.steps[stepIndex].type == "backward")
        {
            straightLine();
        }
    }
}

float calculateDistance(float x1, float y1, float x2, float y2)
{
    // just some math
}

bool isDeplacementAtDestination()
{
   // just some math
}

bool isTurnAtDestination()
{

    float currentAngle = getAngle();
    float targetAngle = strategy.steps[stepIndex].angle;
    if (abs(currentAngle - targetAngle) < .3)
    {
        if (millis() - lastZeroTime >= 200)
        {
            return true;
        }
    }
    else
    {
        lastZeroTime = millis();
    }
    return false;
}

void setPidMove(int kp, int ki, int kd)
{
    KpD = kp;
    KiD = ki;
    KdD = kd;
}

void resetPidController()
{
    stepIndex = 0;
    error = 0;
    totalErrors = 0;
    dError = 0;
    lastError = 0;
    targetSpeed = 0;
    adjust = 0;
    lastZeroTime = 0;
}

I commented some of the code with "just some math" for readability.

I don't really know if it's just bad architecture or bad task management (certainly both)

One strange thing is that I put a log in the main loop with a delay(1000) to check if it was still running and all of the tasks were created fine

If you have any idea on how i can fixed that, it would be perfect.

Better suspend and resume the task.

It takes some time to remove a task. Try to find out how to check for full task removal.

1 Like

Better than that, have the task enter the Blocked state and pend on an event bit, direct notification, queue entry, etc that signals that it's time to move again.

1 Like

Thank you !
I did not really understand how task delete works so for now I switched to suspend/resume and it works. that's enough for me for now.

Thank you !
I'm keeping this aside to improve my code

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.