Je fais un vecteur de "waypoints" sur l'Arduino. Chaque waypoint est un objet. L’Arduino devra évidemment stocker plusieurs points de cheminement pour la navigation. Mais au lieu de stocker ces points de cheminement dans un tableau préprogrammé standard, l'utilisateur devra pouvoir ajouter, supprimer des points de cheminement et les déplacer. Malheureusement, l’Arduino n’offre pas un type de vecteur en tant que bibliothèque intégrée.
Je réfléchis actuellement à deux options:
Dans Conteneur pour des objets comme C++ 'vector'?, quelqu'un a posté une bibliothèque à usage général. Il ne contient aucune suppression d'index ni aucune opération de déplacement. Mais il contient certaines stratégies de gestion de la mémoire.
J'ai utilisé malloc, dealloc, calloc dans le passé. Mais je n'aime pas du tout cette option, surtout avec les cours. Mais est-ce une meilleure option dans mon sénario?
Lequel est le meilleur chemin à suivre?
C++ standard pour Arduino pourrait être une option. Il vous permet d’utiliser le STLvector dans Arduino.
On dirait que vous voudriez implémenter une simple liste chaînée. Une liste chaînée vous permet de déplacer des objets (points de passage, dans votre cas) sans la surcharge associée aux vecteurs C++.
Voici une implémentation sur GitHub .
L'arduino a une mémoire limitée, vous devez donc savoir combien de points de passage vous autoriserez. Dans ce cas, un simple tableau contenant des pointeurs de mémoire (adresses) des points de route alloués fournira la séquence/l'ordre dont vous avez besoin. Garder un emplacement de matrice libre en tant que zone de travail permettra de déplacer les points de cheminement (réordonné).
Vous pouvez écrire cette classe de modèle LinkedList et l'appeler simplement où vous voulez:
#ifndef LinkedList_hpp
#define LinkedList_hpp
template <class T>
class ListNode {
public:
T element;
ListNode* next;
ListNode* prev;
ListNode(T element, ListNode* prev, ListNode* next) : element(element)
{
this->next = next;
this->prev = prev;
};
};
template <class T>
class LinkedList {
private:
int length;
ListNode<T>* head;
ListNode<T>* tail;
ListNode<T>* curr;
public:
LinkedList();
LinkedList(const LinkedList<T>&);
~LinkedList();
T& getCurrent();
T& First() const;
T& Last() const;
int getLength();
void Append(T);
void DeleteLast();
void DeleteFirst();
void DeleteCurrent();
bool next();
bool moveToStart();
bool prev();
void Delete(T&);
bool Search(T);
void Clear();
void PutFirstToLast();
void Update(T elem);
LinkedList& operator = (const LinkedList<T>&);
};
template <class T>
LinkedList<T>::LinkedList() {
length = 0;
head = nullptr;
tail = nullptr;
curr = nullptr;
}
template <class T>
LinkedList<T>::LinkedList(const LinkedList<T> & list) {
length = 0;
head = nullptr;
tail = nullptr;
curr = nullptr;
ListNode<T> * temp = list.head;
while(temp != nullptr)
{
Append(temp->element);
temp = temp->next;
}
}
template <class T>
LinkedList<T> & LinkedList<T>::operator=(const LinkedList<T> & list)
{
Clear();
ListNode<T> * temp = list.head;
while(temp != nullptr)
{
Append(temp->element);
temp = temp->next;
}
return *this;
}
template <class T>
LinkedList<T>::~LinkedList() {
Clear();
}
template<class T>
T& LinkedList<T>::getCurrent()
{
return curr->element;
}
template<class T>
T& LinkedList<T>::First() const
{
return head->element;
}
template<class T>
T& LinkedList<T>::Last() const
{
return tail->element;
}
template<class T>
int LinkedList<T>::getLength()
{
return length;
}
template <class T>
void LinkedList<T>::Append(T element)
{
ListNode<T> * node = new ListNode<T>(element, tail, nullptr);
if(length == 0)
curr = tail = head = node;
else {
tail->next = node;
tail = node;
}
length++;
}
template <class T>
void LinkedList<T>::DeleteLast()
{
if(length == 0)
return;
curr = tail;
DeleteCurrent();
}
template <class T>
void LinkedList<T>::DeleteFirst()
{
if(length == 0)
return;
curr = head;
DeleteCurrent();
}
template <class T>
bool LinkedList<T>::next()
{
if(length == 0)
return false;
if(curr->next == nullptr)
return false;
curr = curr->next;
return true;
}
template <class T>
bool LinkedList<T>::moveToStart()
{
curr = head;
return length != 0;
}
template<class T>
bool LinkedList<T>::prev()
{
if(length == 0)
return false;
if(curr->prev != nullptr)
return false;
curr = curr->prev;
return true;
}
template <class T>
void LinkedList<T>::Delete(T & elem)
{
if(Search(elem))
DeleteCurrent();
}
template <class T>
void LinkedList<T>::DeleteCurrent()
{
if(length == 0)
return;
length--;
ListNode<T> * temp = curr;
if(temp->prev != nullptr)
temp->prev->next = temp->next;
if(temp->next != nullptr)
temp->next->prev = temp->prev;
if(length == 0)
head = curr = tail = nullptr;
else if(curr == head)
curr = head = head->next;
else if(curr == tail)
curr = tail = tail->prev;
else
curr = curr->prev;
delete temp;
}
template <class T>
bool LinkedList<T>::Search(T elem)
{
if(length == 0)
return false;
if(moveToStart())
do {
if(curr->element == elem)
return true;
} while (next());
return false;
}
template <class T>
void LinkedList<T>::PutFirstToLast()
{
if(length < 2)
return;
ListNode<T>* temp = head->next;
head->next->prev = nullptr;
head->next = nullptr;
head->prev = tail;
tail->next = head;
tail = head;
head = temp;
}
template <class T>
void LinkedList<T>::Update(T elem)
{
if(Search(elem))
curr->element = elem;
}
template <class T>
void LinkedList<T>::Clear()
{
if(length == 0)
return;
ListNode<T> * temp = head;
while(temp != nullptr)
{
head = head->next;
delete temp;
temp = head;
}
head = curr = tail = nullptr;
}
#endif
Utilisez cette classe comme suit:
LinkedList<int> list;
list.append(1);
list.append(2);
list.append(3);
list.append(4);
int my_integer;
if(list.moveToStart())
do{
my_integer = list.getCurrent();
}while(list.next());
Vous pouvez également avoir un tableau fixe de structures de points de route et inclure une variable dans la structure si le point de route est utilisé ou non. Lors de l'ajout d'un point de cheminement, il vous suffit de parcourir le tableau jusqu'à ce que vous trouviez une structure inutilisée.