bonjour a tous.
Ceci est mon premier post sur un forum, excusez moi d'avance si tout n'est pas clair.
j'envoi par Bluetooth une commande a mon robot, mon problème est que selon le temps d'appui sur le bouton ma commander mon mouvement est jouer plusieurs fois alors que je veux la jouer une seul fois .je pense que le temps d'appui enregistre dans le buffer plusieurs fois ma commande.
avez vous une solution je vous remercie par avance.
#include <RC100.h>
// **** Global Parameters for DXLs *********
#include <Dynamixel2Arduino.h>
#define DXL_SERIAL_1 Serial1 //Serial1 is for DXL port on OpenRB-150
//#define DEBUG_SERIAL Serial
// **** Global Parameters for DXLs *********
const uint8_t BROADCAST_ID = 254;
const uint8_t DXL_ID1 = 1;
const uint8_t DXL_ID2 = 2;
const uint8_t DXL_ID3 = 3;
const uint8_t DXL_ID4 = 4;
const uint8_t DXL_ID5 = 5;
const uint8_t DXL_ID6 = 6;
const uint8_t DXL_ID7 = 7;
const uint8_t DXL_ID8 = 8;
const uint8_t DXL_ID9 = 9;
const uint8_t DXL_ID10 = 10;
const uint8_t DXL_ID11 = 11;
const uint8_t DXL_ID12 = 12;
const uint8_t DXL_ID13 = 13;
const uint8_t DXL_ID14 = 14;
const uint8_t DXL_ID15 = 15;
const uint8_t DXL_ID16 = 16;
Dynamixel2Arduino dxl_mini(DXL_SERIAL_1);
// Number of DXLs used in robot
const float DXL_PROTOCOL_VERSION = 2.0;
const uint8_t GP_DXL_CNT = 16; // nombre de DXL utilisés en mode Contrôle de position
const uint8_t GP_DXL_ID_LIST[GP_DXL_CNT] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; //ID de servo définis en mode Contrôle de position
const uint16_t ADDR_X_PRESENT_POSITION = 37; // (XL-320)
const uint16_t LEN_X_PRESENT_POSITION = 2; // (XL-320)
const uint16_t ADDR_X_GOAL_POSITION = 30; // (XL-320)
const uint16_t LEN_X_GOAL_POSITION = 2; // (XL-320)
const uint16_t ADDR_X_MOVING_SPEED = 32; // (XL-320) adress 32 byt 2 0-2047
const uint16_t LEN_X_MOVING_SPEED = 2; // (XL-320)
const uint16_t ADDR_X_TORQUE_ENABLE = 24; // (XL-320) TORQUE_ENABLE adress 24 0 off 1 on
const uint16_t LEN_X_TORQUE_ENABLE = 1;
const uint8_t CONTROL_MODE = 2; // for XL320 adress 11 byt 1 mode 2 =joint
uint16_t Current_Pose[GP_DXL_CNT] = { 0 };
//uint16_t Step = 10;// Étape
// ********** RC100 settings *************
#include <RC100.h>
RC100 RC_2; // Instalation de la télécommande via Serial2
uint16_t RcvData_2 = 0;
bool UP = false;
bool DOWN = false;
bool LEFT = false;
bool RIGHT = false;
// ********** End of Global Parameters Definition
//**** This namespace is required to use Control table item names
//using namespace ControlTableItem;
ParamForSyncWriteInst_t MS_sync_write_param; // Parameters structure for MS packet
ParamForSyncWriteInst_t GP_sync_write_param; // Parameters structure for SW GP packet
ParamForSyncReadInst_t GP_sync_read_param; // Parameters structure for SR GP packet
RecvInfoFromStatusInst_t GP_read_result; // Structure for results of SR PP command
uint8_t dxl_error = 0; // Dynamixel error
int32_t dxl_MOVING_SPEED[GP_DXL_CNT] = { 0 }; // Tableau de position vitesse
int32_t dxl_present_position[GP_DXL_CNT] = { 0 }; // Tableau de position actuelle
int32_t dxl_goal_position[GP_DXL_CNT] = { 0 }; // Tableau de position d'objectif
bool read_present_positions_OK = false;
// Section MOUVEMENT
bool check_motion();
bool B_6 = false; /////////////////////////////////////
/*void myDelay (unsigned long combien_de_temps)
{
unsigned long start = millis ();
if (millis () - start <= combien_de_temps)//
{ }
} */
int GP_time = dxl_MOVING_SPEED[200];
int _STEP_TIME_0 = millis();
int STEP_TIME_1 = millis();
float pose_init[17] = { 390, 0, 0, -73.24, 73.24, 0, 0, 0, 0, -26.37, 26.37, 29.3, -29.3, 13.18, -13.18, 0, 0 };
float salut_main[6][17] = { { 50, -0.29, -150, -73.54, 72.36, -0.29, 0.59, -0.29, -0.29, -26.66, 26.07, 29, -29.59, 12.89, -13.48, -0.29, -0.29 }, // 50 75 100 125 150 275
{ 25, -0.29, -150, -73.54, 51.27, -0.29, -33.69, -0.29, -0.29, -26.66, 26.07, 29, -29.59, 12.89, -13.48, -0.29, -0.29 },
{ 25, -0.29, -150, -73.54, 91.7, -0.29, 32.81, -0.29, -0.29, -26.66, 26.07, 29, -29.59, 12.89, -13.48, -0.29, -0.29 },
{ 25, -0.29, -150, -73.54, 51.27, -0.29, -33.69, -0.29, -0.29, -26.66, 26.07, 29, -29.59, 12.89, -13.48, -0.29, -0.29 },
{ 25, -0.29, -150, -73.54, 91.7, -0.29, 32.81, -0.29, -0.29, -26.66, 26.07, 29, -29.59, 12.89, -13.48, -0.29, -0.29 },
{ 125, 0, 0, -73.24, 73.24, 0, 0, 0, 0, -26.37, 26.37, 29.3, -29.3, 13.18, -13.18, 0, 0 } };
float salut_2[6][17] = { {
25,
-22.27,
-44.24,
-73.24,
73.24,
0,
0,
0,
0,
-26.37,
26.07,
29.3,
-29.3,
13.18,
-13.48,
0,
0,
}, //25 75 150 275 350 400
{ 50, -22.27, -44.24, -62.99, 92.58, -71.78, 58.59, 0, 0, -26.37, 26.07, 29.3, -29.3, 13.18, -13.48, 0, 0 },
{ 75, -22.27, -69.73, -62.99, 92.58, -71.78, 58.59, 0, 0, -79.39, 82.91, 29.3, -29.3, -10.25, 10.55, 0, 0 },
{ 125, -22.27, -69.73, -62.99, 92.58, -71.78, 58.59, 0, 0, -79.39, 82.91, 29.3, -29.3, -10.25, 10.55, 0, 0 },
{ 75, -22.27, -44.24, -73.24, 73.24, 0, 0, 0, 0, -26.37, 26.07, 29.3, -29.3, 13.18, -13.48, 0, 0 },
{ 50, 0, 0, -73.24, 73.24, 0, 0, 0, 0, -26.37, 26.37, 29.3, -29.3, 13.18, -13.18, 0, 0 } };
// ********** Function prototypes
//int GP_time = dxl_MOVING_SPEED[300]; //////////////////////////////////////
int CalcAngle2Raw(int angle) {
return (int)(round((angle * 1023.0 / 300.0 + 512.0))); // return (int)(round((angle * 1023.0 / 300.0 + 512.0)));XL 320
} // fin de CalcAngle2Raw (angle int)
int i = 16;
int frame_no = 0;
int goal_position_raw = 0;
// Cet espace de noms est requis pour utiliser les noms d'éléments de la table de contrôle
using namespace ControlTableItem;
void setup() {
int goal_position_raw = 0; // raw valeur brute de la position de l'objectif DXL
Serial.begin(115200);
while (!Serial)
; // attendez que l'opérateur ouvre Serial Monitor
// *****Configuration des Dynamixels pour mini ***
dxl_mini.begin(1000000); // débit en bauds du port DXL sur 1 Mbps pour XL320
dxl_mini.setPortProtocolVersion(DXL_PROTOCOL_VERSION);
dxl_mini.scan();
Serial.println("Fin de la numérisation des DXL du robot ");
// Préparation du paquet GP SW
MS_sync_write_param.addr = ADDR_X_MOVING_SPEED;
MS_sync_write_param.length = LEN_X_MOVING_SPEED;
MS_sync_write_param.id_count = GP_DXL_CNT;
for (int i = 0; i < GP_DXL_CNT; i++) {
MS_sync_write_param.xel[i].id = GP_DXL_ID_LIST[i];
}
Serial.println("Fin de la préparation du paquet MS SW");
// Préparation du paquet GP SR
GP_sync_read_param.addr = ADDR_X_PRESENT_POSITION; // Present Position of DYNAMIXEL-X series
GP_sync_read_param.length = LEN_X_PRESENT_POSITION;
GP_sync_read_param.id_count = GP_DXL_CNT; // Number of servos in Position Control Mode
for (int i = 0; i < GP_DXL_CNT; i++) {
GP_sync_read_param.xel[i].id = GP_DXL_ID_LIST[i];
}
Serial.println("Fin de la préparation du paquet GP SR");
// Préparation du paquet GP SW
GP_sync_write_param.addr = ADDR_X_GOAL_POSITION;
GP_sync_write_param.length = LEN_X_GOAL_POSITION;
GP_sync_write_param.id_count = GP_DXL_CNT;
for (int i = 0; i < GP_DXL_CNT; i++) {
GP_sync_write_param.xel[i].id = GP_DXL_ID_LIST[i];
}
Serial.println("Fin de la préparation du paquet GP SW");
// Configuration des servos GP dans la zone EEPROM : mode contrôle contrôle de position
// et dans la zone RAM : vitesse dxl du profil
for (int i = 0; i < GP_DXL_CNT; i++) {
dxl_mini.torqueOff(GP_DXL_ID_LIST[i]); // Torque OFF
dxl_mini.writeControlTableItem(MOVING_SPEED, GP_DXL_ID_LIST[i], 0); // Définition des vitesses de déplacement initiales
dxl_mini.setOperatingMode(GP_DXL_ID_LIST[i], OP_POSITION);
dxl_mini.torqueOn(GP_DXL_ID_LIST[i]); // Torque ON
delay(100); // attendez un peu avant de travailler dans la zone RAM
}
Serial.println("Fin de la configuration des servos GP");
delay(1000);
Serial.begin(115200);
RC_2.begin(2); // RC_2 utilisant Serial2 - Port UART 4 broches - débit en bauds 57 600 bps dans RC100.cpp
dxl_mini.begin(1000000);
dxl_mini.setPortProtocolVersion(DXL_PROTOCOL_VERSION);
for (int i = 0; i < GP_DXL_CNT; i++) {
dxl_mini.ping(GP_DXL_ID_LIST[i]);
dxl_mini.torqueOff(GP_DXL_ID_LIST[i]);
//dxl_mini.writeControlTableItem(MOVING_SPEED, GP_DXL_ID_LIST[i], 200);
dxl_mini.setOperatingMode(GP_DXL_ID_LIST[i], OP_POSITION);
dxl_mini.torqueOn(GP_DXL_ID_LIST[i]);
delay(100); // attendez un peu avant de travailler dans la zone RAM
}
Serial.println("Mettre le robot dans la pose initiale");
// Allouez la valeur brute de chaque position d'objectif dans le paquet GP SW, un DXL à la fois en utilisant les valeurs du tableau global _[1] à _[16]
for (int i = 0; i < GP_DXL_CNT; i++) // DXL 1 à 16
{
_STEP_TIME_0 = (int)(round(pose_init[0])); //c'est-à-dire STEP TIME 0 = millis ///////////////////////////////////////
// Réglez le robot sur la pose _ via SyncWrite
goal_position_raw = CalcAngle2Raw(pose_init[i + 1]); // convertir l'angle de mouvement en position d'objectif brute [0-1023], _[0] n'est pas utilisé ici
memcpy(GP_sync_write_param.xel[i].data, &goal_position_raw, sizeof(goal_position_raw));
dxl_mini.writeControlTableItem(MOVING_SPEED, GP_DXL_ID_LIST[i], 200);
dxl_mini.setOperatingMode(GP_DXL_ID_LIST[i], OP_POSITION);
}
dxl_mini.syncWrite(GP_sync_write_param); // send GP SW Packet
delay(1000);
Serial.println("Fin de la configuration pose init");
}
void loop() {
// récupérer les positions actuelles des actionneurs
for (int i = 0; i < GP_DXL_CNT; i++) {
Current_Pose[i] = dxl_mini.getPresentPosition(GP_DXL_ID_LIST[i]);
}
// effacer toutes les commandes du robot de Serial2
UP = false;
DOWN = false;
LEFT = false;
RIGHT = false;
RcvData_2 = 0;
// Traitement des nouveaux boutons RC-100
if (RC_2.available()) {
RcvData_2 = RC_2.readData();
if (RcvData_2 == 0) {
Serial.println("Tous les boutons libérés via Serial2");
}
if ((RcvData_2 & RC100_BTN_U) > 0) {
Serial.println("Button UP poussé via Serial2");
UP = true;
}
if ((RcvData_2 & RC100_BTN_D) > 0) {
Serial.println("Button DOWN poussé via Serial2");
DOWN = true;
}
if ((RcvData_2 & RC100_BTN_L) > 0) {
Serial.println("Button LEFT poussé via Serial2");
LEFT = true;
}
if ((RcvData_2 & RC100_BTN_R) > 0) {
Serial.println("Button RIGHT poussé via Serial2");
RIGHT = true;
}
}
// Faire fonctionner le robot selon les commandes de l'opérateur via Serial2
if (UP == true) {
Serial.println("jouer salut main");
for (int frame_no = 0; frame_no < 6; frame_no++) // 6 images de mouvement ont été définies pour le mouvement bras
{
STEP_TIME_1 = (int)(round(salut_main[frame_no][0])); //c'est-à-dire STEP TIME 1 = millis
for (int i = 0; i < GP_DXL_CNT; i++) // Définition des valeurs GP brutes pour les DXL 1 à 16
{
goal_position_raw = (CalcAngle2Raw(salut_main[frame_no][i + 1])); //convertir l'angle de mouvement en Raw GP
memcpy(GP_sync_write_param.xel[i].data, &goal_position_raw, sizeof(goal_position_raw));
dxl_mini.writeControlTableItem(MOVING_SPEED, GP_DXL_ID_LIST[i], 200);
//dxl_mini.setOperatingMode(GP_DXL_ID_LIST[i], OP_POSITION);
}
dxl_mini.syncWrite(GP_sync_write_param);
delay(390); // en attendant que chaque image clé soit jouée en ms
}
}
if (DOWN == true) {
Serial.println("jouer salut 2");
for (int frame_no = 0; frame_no < 6; frame_no++) // 6 images de mouvement ont été définies pour le mouvement bras
{
STEP_TIME_1 = (int)(round(salut_2[frame_no][0]));
for (int i = 0; i < GP_DXL_CNT; i++) // Définition des valeurs GP brutes pour les DXL 1 à 16
{
//STEP_TIME_1 = (int)(round(salut_2[frame_no][0] ));
goal_position_raw = (CalcAngle2Raw(salut_2[frame_no][i + 1])); //convertir l'angle de mouvement en Raw GP
memcpy(GP_sync_write_param.xel[i].data, &goal_position_raw, sizeof(goal_position_raw));
dxl_mini.writeControlTableItem(MOVING_SPEED, GP_DXL_ID_LIST[i], 400);
// dxl_mini.setOperatingMode(GP_DXL_ID_LIST[i], OP_POSITION);/////////////////////////
}
dxl_mini.syncWrite(GP_sync_write_param);
delay(390); // en attendant que chaque image clé soit jouée en ms
} // fin de pour (numéro de trame)
}
}