@@ -678,6 +678,10 @@ bool Dynamixel::checkReadType()
678
678
uint16_t indirect_addr[2 ]; // [i-1], [i]
679
679
uint8_t indirect_size[2 ]; // [i-1], [i]
680
680
681
+ if (CheckIndirectReadAvailable (read_data_list_.at (dxl_index - 1 ).id ) != DxlError::OK) {
682
+ return BULK;
683
+ }
684
+
681
685
if (!dxl_info_.GetDxlControlItem (
682
686
read_data_list_.at (dxl_index).id , " Indirect Data Read" , indirect_addr[1 ],
683
687
indirect_size[1 ]) ||
@@ -816,7 +820,7 @@ DxlError Dynamixel::SetSyncReadHandler(std::vector<uint8_t> id_arr)
816
820
IN_ADDR, indirect_info_read_[id_arr.at (0 )].size );
817
821
818
822
group_sync_read_ =
819
- new dynamixel::GroupFastSyncRead (
823
+ new dynamixel::GroupSyncRead (
820
824
port_handler_, packet_handler_,
821
825
IN_ADDR, indirect_info_read_[id_arr.at (0 )].size );
822
826
@@ -857,15 +861,64 @@ DxlError Dynamixel::GetDxlValueFromSyncRead(double period_ms)
857
861
858
862
DxlError Dynamixel::SetBulkReadItemAndHandler ()
859
863
{
860
- std::vector<uint8_t > id_arr;
864
+ group_bulk_read_ = new dynamixel::GroupBulkRead (port_handler_, packet_handler_);
865
+
866
+ std::vector<uint8_t > indirect_id_arr;
867
+ std::vector<uint8_t > direct_id_arr;
868
+
869
+ std::vector<RWItemList> indirect_read_data_list;
870
+ std::vector<RWItemList> direct_read_data_list;
871
+
861
872
for (auto it_read_data : read_data_list_) {
862
- id_arr.push_back (it_read_data.id );
873
+ if (CheckIndirectReadAvailable (it_read_data.id ) == DxlError::OK) {
874
+ indirect_id_arr.push_back (it_read_data.id );
875
+ indirect_read_data_list.push_back (it_read_data);
876
+ } else {
877
+ direct_id_arr.push_back (it_read_data.id );
878
+ direct_read_data_list.push_back (it_read_data);
879
+ }
863
880
}
864
881
865
- DynamixelDisable (id_arr);
866
- ResetIndirectRead (id_arr);
882
+ for (auto it_read_data : direct_read_data_list) {
883
+ if (it_read_data.item_addr .empty () || it_read_data.item_size .empty ()) {
884
+ continue ;
885
+ }
886
+ // Calculate min address and max end address
887
+ uint16_t min_addr = it_read_data.item_addr [0 ];
888
+ uint16_t max_end_addr = it_read_data.item_addr [0 ] + it_read_data.item_size [0 ];
889
+ for (size_t item_index = 1 ; item_index < it_read_data.item_addr .size (); ++item_index) {
890
+ uint16_t addr = it_read_data.item_addr [item_index];
891
+ uint16_t size = it_read_data.item_size [item_index];
892
+ if (addr < min_addr) min_addr = addr;
893
+ if (addr + size > max_end_addr) max_end_addr = addr + size;
894
+ }
895
+ uint8_t total_size = max_end_addr - min_addr;
896
+ // Concatenate all item names with '+'
897
+ std::string group_item_names;
898
+ for (size_t i = 0 ; i < it_read_data.item_name .size (); ++i) {
899
+ group_item_names += it_read_data.item_name [i];
900
+ if (i + 1 < it_read_data.item_name .size ()) group_item_names += " + " ;
901
+ }
902
+ // Call AddDirectRead once per id
903
+ if (AddDirectRead (
904
+ it_read_data.id ,
905
+ group_item_names,
906
+ min_addr,
907
+ total_size) != DxlError::OK)
908
+ {
909
+ fprintf (stderr, " Cannot set the BulkRead handler.\n " );
910
+ return DxlError::BULK_READ_FAIL;
911
+ }
912
+ fprintf (
913
+ stderr,
914
+ " set bulk read (direct addr) : addr %d, size %d\n " ,
915
+ min_addr, total_size);
916
+ }
867
917
868
- for (auto it_read_data : read_data_list_) {
918
+ DynamixelDisable (indirect_id_arr);
919
+ ResetIndirectRead (indirect_id_arr);
920
+
921
+ for (auto it_read_data : indirect_read_data_list) {
869
922
for (size_t item_index = 0 ; item_index < it_read_data.item_name .size ();
870
923
item_index++)
871
924
{
@@ -880,17 +933,22 @@ DxlError Dynamixel::SetBulkReadItemAndHandler()
880
933
stderr, " [ID:%03d] Add Indirect Address Read Item : [%s]\n " ,
881
934
it_read_data.id ,
882
935
it_read_data.item_name .at (item_index).c_str ());
883
- } else {
936
+ } else if (result == DxlError::SET_BULK_READ_FAIL) {
884
937
fprintf (
885
938
stderr, " [ID:%03d] Failed to Indirect Address Read Item : [%s], %d\n " ,
886
939
it_read_data.id ,
887
940
it_read_data.item_name .at (item_index).c_str (),
888
941
result);
942
+ } else if (result == DxlError::CANNOT_FIND_CONTROL_ITEM) {
943
+ fprintf (
944
+ stderr, " [ID:%03d] 'Indirect Address Read' is not defined in control table, Cannot set Indirect Address Read for : [%s]\n " ,
945
+ it_read_data.id ,
946
+ it_read_data.item_name .at (item_index).c_str ());
889
947
}
890
948
}
891
949
}
892
-
893
- if (SetBulkReadHandler (id_arr ) != DxlError::OK) {
950
+
951
+ if (SetBulkReadHandler (indirect_id_arr ) != DxlError::OK) {
894
952
fprintf (stderr, " Cannot set the BulkRead handler.\n " );
895
953
return DxlError::BULK_READ_FAIL;
896
954
}
@@ -919,11 +977,9 @@ DxlError Dynamixel::SetBulkReadHandler(std::vector<uint8_t> id_arr)
919
977
fprintf (
920
978
stderr,
921
979
" set bulk read (indirect addr) : addr %d, size %d\n " ,
922
- IN_ADDR, indirect_info_read_[id_arr. at ( 0 ) ].size );
980
+ IN_ADDR, indirect_info_read_[it_id ].size );
923
981
}
924
982
925
- group_bulk_read_ = new dynamixel::GroupFastBulkRead (port_handler_, packet_handler_);
926
-
927
983
for (auto it_id : id_arr) {
928
984
uint8_t ID = it_id;
929
985
uint16_t ADDR = indirect_info_read_[ID].indirect_data_addr ;
@@ -941,6 +997,17 @@ DxlError Dynamixel::SetBulkReadHandler(std::vector<uint8_t> id_arr)
941
997
return DxlError::OK;
942
998
}
943
999
1000
+ DxlError Dynamixel::AddDirectRead (uint8_t id, std::string item_name, uint16_t item_addr, uint8_t item_size)
1001
+ {
1002
+ if (group_bulk_read_->addParam (id, item_addr, item_size) == true ) {
1003
+ fprintf (stderr, " [ID:%03d] Add BulkRead item : [%s][%d][%d]\n " , id, item_name.c_str (), item_addr, item_size);
1004
+ } else {
1005
+ fprintf (stderr, " [ID:%03d] Failed to BulkRead item : [%s][%d][%d]\n " , id, item_name.c_str (), item_addr, item_size);
1006
+ return DxlError::SET_BULK_READ_FAIL;
1007
+ }
1008
+ return DxlError::OK;
1009
+ }
1010
+
944
1011
DxlError Dynamixel::GetDxlValueFromBulkRead (double period_ms)
945
1012
{
946
1013
DxlError comm_result = ProcessReadCommunication (
@@ -953,22 +1020,33 @@ DxlError Dynamixel::GetDxlValueFromBulkRead(double period_ms)
953
1020
uint8_t id = it_read_data.id ;
954
1021
uint16_t indirect_addr = indirect_info_read_[id].indirect_data_addr ;
955
1022
956
- ProcessReadData (
957
- id,
958
- indirect_addr,
959
- indirect_info_read_[id].item_name ,
960
- indirect_info_read_[id].item_size ,
961
- it_read_data.item_data_ptr_vec ,
962
- [this ](uint8_t id, uint16_t addr, uint8_t size) {
963
- return group_bulk_read_->getData (id, addr, size);
964
- });
1023
+ if (CheckIndirectReadAvailable (id) != DxlError::OK) {
1024
+ ProcessDirectReadData (
1025
+ id,
1026
+ it_read_data.item_addr ,
1027
+ it_read_data.item_size ,
1028
+ it_read_data.item_data_ptr_vec ,
1029
+ [this ](uint8_t id, uint16_t addr, uint8_t size) {
1030
+ return group_bulk_read_->getData (id, addr, size);
1031
+ });
1032
+ } else {
1033
+ ProcessReadData (
1034
+ id,
1035
+ indirect_addr,
1036
+ indirect_info_read_[id].item_name ,
1037
+ indirect_info_read_[id].item_size ,
1038
+ it_read_data.item_data_ptr_vec ,
1039
+ [this ](uint8_t id, uint16_t addr, uint8_t size) {
1040
+ return group_bulk_read_->getData (id, addr, size);
1041
+ });
1042
+ }
965
1043
}
966
1044
return DxlError::OK;
967
1045
}
968
1046
969
1047
DxlError Dynamixel::ProcessReadCommunication (
970
- dynamixel::GroupFastSyncRead * group_sync_read,
971
- dynamixel::GroupFastBulkRead * group_bulk_read,
1048
+ dynamixel::GroupSyncRead * group_sync_read,
1049
+ dynamixel::GroupBulkRead * group_bulk_read,
972
1050
dynamixel::PortHandler * port_handler,
973
1051
double period_ms,
974
1052
bool is_sync)
@@ -1055,18 +1133,50 @@ DxlError Dynamixel::ProcessReadData(
1055
1133
return DxlError::OK;
1056
1134
}
1057
1135
1136
+ DxlError Dynamixel::ProcessDirectReadData (
1137
+ uint8_t id,
1138
+ const std::vector<uint16_t > & item_addrs,
1139
+ const std::vector<uint8_t > & item_sizes,
1140
+ const std::vector<std::shared_ptr<double >> & data_ptrs,
1141
+ std::function<uint32_t (uint8_t , uint16_t , uint8_t )> get_data_func)
1142
+ {
1143
+ for (size_t item_index = 0 ; item_index < item_addrs.size (); item_index++) {
1144
+ uint16_t current_addr = item_addrs[item_index];
1145
+ uint8_t size = item_sizes[item_index];
1146
+
1147
+ uint32_t dxl_getdata = get_data_func (id, current_addr, size);
1148
+
1149
+ *data_ptrs[item_index] = static_cast <double >(dxl_getdata);
1150
+ }
1151
+ return DxlError::OK;
1152
+ }
1058
1153
1059
1154
void Dynamixel::ResetIndirectRead (std::vector<uint8_t > id_arr)
1060
1155
{
1061
1156
IndirectInfo temp;
1062
- temp.cnt = temp.size = 0 ;
1157
+ temp.indirect_data_addr = 0 ;
1158
+ temp.size = 0 ;
1159
+ temp.cnt = 0 ;
1063
1160
temp.item_name .clear ();
1064
1161
temp.item_size .clear ();
1065
1162
for (auto it_id : id_arr) {
1066
1163
indirect_info_read_[it_id] = temp;
1067
1164
}
1068
1165
}
1069
1166
1167
+ DxlError Dynamixel::CheckIndirectReadAvailable (uint8_t id)
1168
+ {
1169
+ uint16_t INDIRECT_ADDR;
1170
+ uint8_t INDIRECT_SIZE;
1171
+ if (dxl_info_.GetDxlControlItem (
1172
+ id, " Indirect Address Read" ,
1173
+ INDIRECT_ADDR, INDIRECT_SIZE) == false )
1174
+ {
1175
+ return DxlError::CANNOT_FIND_CONTROL_ITEM;
1176
+ }
1177
+ return DxlError::OK;
1178
+ }
1179
+
1070
1180
DxlError Dynamixel::AddIndirectRead (
1071
1181
uint8_t id,
1072
1182
std::string item_name,
@@ -1273,7 +1383,7 @@ DxlError Dynamixel::SetBulkWriteHandler(std::vector<uint8_t> id_arr)
1273
1383
fprintf (
1274
1384
stderr,
1275
1385
" set bulk write (indirect addr) : addr %d, size %d\n " ,
1276
- IN_ADDR, indirect_info_write_[id_arr. at ( 0 ) ].size );
1386
+ IN_ADDR, indirect_info_write_[it_id ].size );
1277
1387
}
1278
1388
1279
1389
group_bulk_write_ = new dynamixel::GroupBulkWrite (port_handler_, packet_handler_);
@@ -1336,7 +1446,9 @@ DxlError Dynamixel::SetDxlValueToBulkWrite()
1336
1446
void Dynamixel::ResetIndirectWrite (std::vector<uint8_t > id_arr)
1337
1447
{
1338
1448
IndirectInfo temp;
1339
- temp.cnt = temp.size = 0 ;
1449
+ temp.indirect_data_addr = 0 ;
1450
+ temp.size = 0 ;
1451
+ temp.cnt = 0 ;
1340
1452
temp.item_name .clear ();
1341
1453
temp.item_size .clear ();
1342
1454
for (auto it_id : id_arr) {
0 commit comments