17 #define TINY_MASS 1.0e-16 18 #define N_2_COEF 1.6 // alpha 19 #define N_COEF 1.0 // beta 20 #define DOF_COEF -1.0 // gamma 21 #define CONST_COEF 14.4 // delta 27 ofstream
logfile(
"schedule.log");
40 Joint* _last_joint,
const fVec& _proc_costs,
42 int _first_proc,
int _last_proc,
69 for(p_joint_list::const_iterator j=org_outer_joints.begin(); j!=org_outer_joints.end(); j++)
101 for(joint_list::const_iterator
i=org_internal_joints.begin();
i!=org_internal_joints.end();
i++)
164 logfile <<
"create goal (0)" << endl;
180 logfile <<
"create goal (1)" << endl;
193 logfile <<
"target_parent = null, schedule_depth = " <<
schedule_depth <<
", child_id = " << child_id << endl;
195 int _first_proc = 0, _last_proc =
max_procs;
224 if(_last_proc - _first_proc == 1)
228 Joint* next_last = 0;
232 for(joint_list::iterator
i=in_joints.begin();
i!=in_joints.end();
i++)
245 next_last = sim->
Root();
252 int n_internal_joints = internal_joints.size();
253 nodes =
new dpNode* [n_internal_joints];
254 joint_list::iterator j;
256 for(i=0, j=internal_joints.begin(); j!=internal_joints.end(); i++, j++)
259 #if 1 // always generate two non-empty subchains 272 return n_internal_joints;
281 logfile <<
"calc_astar_cost(" << flush;
290 logfile <<
" one process: " << tmp << endl;
307 logfile <<
" child 0: " << tmp <<
" [" << n_myprocs <<
"]" << endl;
321 logfile <<
" child 1: " << tmp <<
" [" << n_myprocs <<
"]" << endl;
330 logfile <<
" final = " << c << endl;
371 all_internal.clear();
382 if(!(*j)->ParentSide())
421 all_internal.push_back(cur);
441 all_internal.push_back(cur);
448 logfile <<
"=== calc_min_subchain_cost ===" << endl;
449 logfile <<
"outer = [" << flush;
451 for(p_joint_list::const_iterator j=_outer_joints.begin(); j!=_outer_joints.end(); j++)
453 logfile <<
" " << (*j)->GetJoint()->name << flush;
454 if(!(*j)->ParentSide())
462 int* n_outer_parent_side =
new int [sim->
NumJoint()];
463 int* n_outer_child_side =
new int [sim->
NumJoint()];
466 n_outer_parent_side[
i] = 0;
467 n_outer_child_side[
i] = 0;
469 for(p_joint_list::const_iterator j=_outer_joints.begin(); j!=_outer_joints.end(); j++)
471 if((*j)->ParentSide())
473 Joint* cur = (*j)->GetJoint();
476 n_outer_child_side[p->i_joint]++;
482 n_outer_parent_side[
i] = _outer_joints.size() - n_outer_child_side[
i];
486 added_joints.clear();
497 for(joint_list::iterator j=sorted_child.begin(); j!=sorted_child.end(); j++)
499 if(n_outer_child_side[
c->i_joint] <= n_outer_child_side[(*j)->i_joint])
502 sorted_child.insert(j,
c);
506 if(!done) sorted_child.push_back(
c);
508 for(joint_list::iterator j=sorted_child.begin(); j!=sorted_child.end(); j++)
513 delete[] n_outer_parent_side;
514 delete[] n_outer_child_side;
520 for(joint_list::const_iterator
i=jlist.begin();
i!=jlist.end();
i++)
522 if(*
i == jnt)
return true;
533 for(p_joint_list::const_iterator j=_outer_joints.begin(); j!=_outer_joints.end(); j++)
542 int my_outer = n_outer_child_side[cur->
i_joint];
543 if(n_outer_parent_side[cur->
i_joint] < n_outer_child_side[cur->
i_joint])
546 my_outer = n_outer_parent_side[cur->
i_joint];
555 for(joint_list::iterator j=sorted_child.begin(); j!=sorted_child.end(); j++)
557 if(n_outer_child_side[
c->i_joint] <= n_outer_child_side[(*j)->i_joint])
560 sorted_child.insert(j,
c);
564 if(!done) sorted_child.push_back(
c);
566 for(joint_list::iterator j=sorted_child.begin(); j!=sorted_child.end(); j++)
570 ret +=
add_to_parent_side(cur, added_joints, n_outer_parent_side, n_outer_child_side);
579 int n_child_outer = n_outer_child_side[
c->i_joint];
580 if(n_child_outer <= my_outer)
584 for(joint_list::iterator
i=smaller_child.begin();
i!=smaller_child.end();
i++)
586 int n = n_outer_child_side[(*i)->i_joint];
587 if(n_child_outer <= n)
589 smaller_child.insert(
i,
c);
596 smaller_child.push_back(
c);
603 for(joint_list::iterator
i=larger_child.begin();
i!=larger_child.end();
i++)
605 int n = n_outer_child_side[(*i)->i_joint];
606 if(n_child_outer <= n)
608 larger_child.insert(
i,
c);
615 larger_child.push_back(
c);
620 for(joint_list::iterator j=smaller_child.begin(); j!=smaller_child.end(); j++)
625 ret +=
add_to_child_side(cur, added_joints, n_outer_parent_side, n_outer_child_side);
627 for(joint_list::iterator j=larger_child.begin(); j!=larger_child.end(); j++)
640 int n_outer = n_outer_parent_side[cur->
i_joint];
641 int n_link_outer = 0;
644 if(!
is_in(added_joints,
c))
649 added_joints.push_back(cur);
651 logfile <<
" adding " << cur->
name <<
", n_outer = " << n_outer <<
", n_link_outer = " << n_link_outer <<
", cost = " << ret << endl;
658 int n_outer = n_outer_child_side[cur->
i_joint];
659 int n_link_outer = 0;
668 if(!
is_in(added_joints,
c) &&
c!=cur)
674 added_joints.push_back(cur);
676 logfile <<
" adding " << cur->
name <<
", n_outer = " << n_outer <<
", n_link_outer = " << n_link_outer <<
", cost = " << ret << endl;
700 joint_list::iterator
f;
704 for(n=cur_leaf;
n; n=n->
Parent())
724 joint_list::iterator
f;
728 for(n=cur_leaf;
n; n=n->
Parent())
754 all_vjoints.push_back(cur);
758 all_joints.push_back(cur);
767 logfile <<
"AutoSchedule(max_procs = " << _max_procs <<
")" << endl;
778 for(joint_list::iterator j=all_vjoints.begin(); j!=all_vjoints.end(); j++)
781 GetPJoint(*j, v_pjoints);
782 init_outer_joints.push_back(v_pjoints[0]);
783 init_outer_joints.push_back(v_pjoints[1]);
787 init_proc_costs.
zero();
795 logfile <<
"pSim::AutoSchedule: goal not found" << endl;
799 cerr <<
"goal found" << endl;
800 cerr <<
"cost = " << goal->
TotalCost() << endl;
802 cerr <<
"proc_costs = " <<
tran(proc_costs) << endl;
803 Joint** joints =
new Joint* [n_joint+all_vjoints.size()];
819 logfile <<
"joints = " << endl;
820 for(joint_list::iterator j=all_internal.begin(); j!=all_internal.end(); j++)
822 logfile <<
" " << count <<
" " << (*j)->name << endl;
827 logfile <<
"current count = " << count <<
", number of vjoints = " << all_vjoints.size() <<
", total n_joint = " << n_joint << endl;
828 logfile <<
"joints = " << endl;
829 for(
int i=0;
i<count;
i++)
833 for(joint_list::iterator j=all_vjoints.begin(); j!=all_vjoints.end(); j++)
836 logfile <<
"[" << count <<
"] = " << joints[count]->
name << endl;
849 _internal_joints_0.clear();
850 _internal_joints_1.clear();
851 joint_list::const_iterator j;
853 for(j=org_internal_joints.begin(); j!=org_internal_joints.end(); j++)
856 if(*j == _last_joint)
860 else if((*j)->isAscendant(_last_joint))
862 _internal_joints_0.push_back(*j);
867 _internal_joints_1.push_back(*j);
877 new_outer_joints.clear();
878 new_outer_joints.push_back(last_pjoint);
879 p_joint_list::const_iterator p;
880 int child_id = (last_pjoint->
ParentSide()) ? 1 : 0;
881 for(p=org_outer_joints.begin(); p!=org_outer_joints.end(); p++)
883 if((*p)->GetJoint()->isAscendant(last_pjoint->
GetJoint()))
886 new_outer_joints.push_back(*p);
888 else if(child_id == 1)
890 new_outer_joints.push_back(*p);
903 subchains->assign_processes(0, max_procs);
905 all_acc_types =
new MPI_Datatype [
max_procs];
907 MPI_Aint** disps =
new MPI_Aint* [
max_procs];
908 MPI_Datatype** oldtypes =
new MPI_Datatype* [
max_procs];
909 int* n_proc_joints =
new int [
max_procs];
913 lengths[
i] =
new int [3*n_joint];
914 disps[
i] =
new MPI_Aint [3*n_joint];
915 oldtypes[
i] =
new MPI_Datatype [3*n_joint];
916 n_proc_joints[
i] = 0;
918 subchains->create_types(n_proc_joints, lengths, disps, oldtypes);
921 MPI_Type_create_struct(n_proc_joints[i], lengths[i], disps[i], oldtypes[i], all_acc_types+i);
922 MPI_Type_commit(all_acc_types+i);
923 logfile <<
"[" << rank <<
"]: all_acc_types[" << i <<
"] = " << all_acc_types[
i] << endl;
930 delete[] oldtypes[
i];
935 delete[] n_proc_joints;
940 int pSubChain::assign_processes(
int start_rank,
int end_rank)
944 if(children[0] && children[1] && children[0] != children[1] &&
946 end_rank > start_rank+1)
948 int n_my_procs = end_rank - start_rank;
949 int n_half_procs = n_my_procs/2;
950 children[0]->assign_processes(start_rank, start_rank+n_half_procs);
951 children[1]->assign_processes(start_rank+n_half_procs, end_rank);
958 children[0]->assign_processes(start_rank, end_rank);
960 if(children[0] != children[1] && children[1])
962 children[1]->assign_processes(start_rank, end_rank);
968 int pSubChain::create_types(
int* n_proc_joints,
int** _lengths, MPI_Aint** _disps, MPI_Datatype** _oldtypes)
975 int n_mat = n_outer_joints * n_outer_joints;
977 int* lengths =
new int [n_mat];
978 MPI_Aint* disps =
new int [n_mat];
979 MPI_Datatype* oldtypes =
new int [n_mat];
980 for(
int i=0;
i<n_outer_joints;
i++)
982 for(
int j=0; j<n_outer_joints; j++)
985 oldtypes[count] = MPI_DOUBLE;
986 MPI_Get_address(Lambda[
i][j].
data(), disps+count);
990 MPI_Type_create_struct(n_mat, lengths, disps, oldtypes, &parent_lambda_type);
991 MPI_Type_commit(&parent_lambda_type);
992 logfile <<
"[" << sim->rank <<
"]: parent_lambda_type = " << parent_lambda_type << endl;
994 for(
int i=0;
i<n_outer_joints;
i++)
997 oldtypes[
i] = MPI_DOUBLE;
998 MPI_Get_address(acc_temp[
i].
data(), disps+
i);
1001 MPI_Type_create_struct(n_outer_joints, lengths, disps, oldtypes, &parent_acc_type);
1002 MPI_Type_commit(&parent_acc_type);
1003 logfile <<
"[" << sim->rank <<
"]: parent_acc_type = " << parent_acc_type << endl;
1008 if(children[0] && rank != children[0]->rank || children[1] && rank != children[1]->rank)
1010 int n_array = n_outer_joints + 2;
1011 int* lengths =
new int [n_array];
1012 MPI_Aint* disps =
new int [n_array];
1013 MPI_Datatype* oldtypes =
new int [n_array];
1015 for(
int i=0;
i<n_outer_joints;
i++)
1018 oldtypes[
i] = MPI_DOUBLE;
1022 lengths[n_outer_joints] = 6;
1023 lengths[n_outer_joints+1] = 6;
1024 oldtypes[n_outer_joints] = MPI_DOUBLE;
1025 oldtypes[n_outer_joints+1] = MPI_DOUBLE;
1026 MPI_Get_address(
last_pjoints[0]->f_final.data(), disps+n_outer_joints);
1027 MPI_Get_address(
last_pjoints[1]->f_final.data(), disps+n_outer_joints+1);
1028 MPI_Type_create_struct(n_outer_joints+2, lengths, disps, oldtypes, &parent_force_type);
1029 MPI_Type_commit(&parent_force_type);
1030 logfile <<
"[" << sim->rank <<
"]: parent_force_type = " << parent_force_type << endl;
1038 int index = n_proc_joints[rank];
1039 _oldtypes[rank][index] = MPI_DOUBLE;
1040 _oldtypes[rank][index+1] = MPI_DOUBLE;
1041 _oldtypes[rank][index+2] = MPI_DOUBLE;
1042 MPI_Get_address(acc_final.data(), _disps[rank]+index);
1043 MPI_Get_address(
last_pjoints[0]->f_final.data(), _disps[rank]+index+1);
1044 MPI_Get_address(
last_pjoints[1]->f_final.data(), _disps[rank]+index+2);
1045 _lengths[rank][index] = acc_final.size();
1046 _lengths[rank][index+1] = 6;
1047 _lengths[rank][index+2] = 6;
1048 n_proc_joints[rank] += 3;
1050 children[0]->create_types(n_proc_joints, _lengths, _disps, _oldtypes);
1051 if(children[0] != children[1]) children[1]->create_types(n_proc_joints, _lengths, _disps, _oldtypes);
1062 if(subchains)
delete subchains;
1065 subchains = default_schedule(0, root);
1067 default_schedule_virtual(root);
1076 if(j->
real)
return 0;
1087 pj0 = joint_info[j->
i_joint].pjoints[0];
1088 pj1 = joint_info[j->
i_joint].pjoints[1];
1095 c1 = default_schedule(sc, j->
brother);
1105 c0 = default_schedule(sc, j->
child);
1122 if(j->
real && contact_vjoint_index(j) < 0)
1125 pj0 = joint_info[j->
i_joint].pjoints[0];
1126 pj1 = joint_info[j->
i_joint].pjoints[1];
1136 default_schedule_virtual(j->
brother);
1137 default_schedule_virtual(j->
child);
1143 children[0]->init();
1144 if(children[0] != children[1]) children[1]->init();
1147 for(
int i=0;
i<n_outer_joints;
i++)
delete[] Lambda[
i];
1151 if(acc_temp)
delete[] acc_temp;
1153 if(vel_temp)
delete[] vel_temp;
1157 if(outer_joints_origin)
delete[] outer_joints_origin;
1158 if(outer_joints_index)
delete[] outer_joints_index;
1160 outer_joints_origin = 0;
1161 outer_joints_index = 0;
1167 Joint* p = links[0]->joint;
1168 links[0]->subchain =
this;
1183 outer_joints_origin =
new int [n_outer_joints];
1184 outer_joints_index =
new int [n_outer_joints];
1186 outer_joints_origin[0] = -1;
1187 outer_joints_index[0] = -1;
1195 outer_joints_origin[n_outer_joints] = -1;
1196 outer_joints_index[n_outer_joints] = -1;
1206 outer_joints_origin[n_outer_joints] = -1;
1207 outer_joints_index[n_outer_joints] = -1;
1217 if(children[0]) last_index[0] = children[0]->get_outer_index(
last_pjoints[0]);
1218 if(children[1]) last_index[1] = children[1]->get_outer_index(
last_pjoints[1]);
1220 n_outer_joints = children[0]->n_outer_joints - 1;
1221 if(children[0] == children[1])
1223 else if(children[1])
1224 n_outer_joints += children[1]->n_outer_joints - 1;
1225 if(n_outer_joints > 0)
1228 outer_joints_origin =
new int [n_outer_joints];
1229 outer_joints_index =
new int [n_outer_joints];
1231 for(i=0; i<children[0]->n_outer_joints; i++)
1236 outer_joints_origin[count] = 0;
1237 if(children[0] == children[1] &&
1241 outer_joints_origin[count] = 1;
1243 outer_joints_index[count] =
i;
1247 if(children[1] && children[0] != children[1])
1249 for(i=0; i<children[1]->n_outer_joints; i++)
1254 outer_joints_origin[count] = 1;
1255 outer_joints_index[count] =
i;
1262 n_links = children[0]->n_links;
1263 if(children[1] && children[0] != children[1])
1264 n_links += children[1]->n_links;
1265 if(links)
delete[] links;
1267 links =
new pLink* [n_links];
1269 for(i=0; i<children[0]->n_links; i++)
1271 links[count] = children[0]->links[
i];
1274 if(children[1] && children[0] != children[1])
1276 for(i=0; i<children[1]->n_links; i++)
1278 links[count] = children[1]->links[
i];
1295 SVS.resize(n_dof, n_dof);
1298 Gamma.resize(n_const, n_const);
1300 Gamma_inv.resize(n_const, n_const);
1303 f_temp.resize(n_const);
1305 colf_temp.resize(n_const);
1309 acc_final.resize(n_dof);
1311 if(n_outer_joints > 0)
1314 Lambda =
new fMat* [n_outer_joints];
1315 acc_temp =
new fVec [n_outer_joints];
1316 vel_temp =
new fVec [n_outer_joints];
1317 for(i=0; i<n_outer_joints; i++)
1319 Lambda[
i] =
new fMat [n_outer_joints];
1320 for(j=0; j<n_outer_joints; j++)
1323 Lambda[
i][j].zero();
1325 acc_temp[
i].resize(6);
1327 vel_temp[
i].resize(6);
1338 if(subchains)
delete subchains;
1341 build_subchain_tree(n_joint, joints, buf);
1344 subchains = *(buf.begin());
1348 cerr <<
"pSim::Schedule(joints): error- invalid joint order" << endl;
1355 for(i=0; i<_n_joints; i++)
1357 cerr <<
"build_subchain_tree " << joints[
i]->
name << endl;
1358 build_subchain_tree(joints[i], buf);
1368 int pj0_done =
false;
1369 int pj1_done =
false;
1372 subchain_list::iterator
i;
1373 for(i=buf.begin(); i!=buf.end(); i++)
1375 if(!pj0_done && in_subchain(*i, pj0->
plink))
1380 if(!to_remove[0]) to_remove[0] = *
i;
1381 else if(!to_remove[1]) to_remove[1] = *
i;
1383 if(!pj1_done && in_subchain(*i, pj1->
plink))
1388 if(!to_remove[0]) to_remove[0] = *
i;
1389 else if(!to_remove[1]) to_remove[1] = *
i;
1392 if(!pj0_done && pj0->
plink)
1397 if(!pj1_done && pj1->
plink)
1402 if(to_remove[0]) buf.remove(to_remove[0]);
1403 if(to_remove[1]) buf.remove(to_remove[1]);
1404 buf.push_front(myp);
1410 if(sc->
links && sc->
links[0] == pl)
return 1;
1411 if(in_subchain(sc->
children[0], pl))
return 1;
1413 in_subchain(sc->
children[1], pl))
return 1;
dpScheduleNode * find_available_parent(int target_depth, int &child_id)
Joint * child
pointer to the child joint
std::list< class pSubChain * > subchain_list
int resize(int i, int j)
Changes the matrix size.
int list_all_internal_joints_sub(Joint *cur, joint_list &all_internal)
int build_subchain_tree(int _n_joints, Joint **joints, subchain_list &buf)
int n_dof
degrees of freedom (0/1/3/6)
std::vector< Joint * > joint_list
int list_all_internal_joints_rev(Joint *cur, joint_list &all_internal)
double calc_cost()
Compute the local cost at the node.
int same_state(dpNode *refnode)
Check if the node's state is the same as refnode. (to remove duplicates)
double calc_astar_cost(dpNode *potential_parent)
Compute the A-star cost at the node (optional).
Forward dynamics computation based on Assembly-Disassembly Algorithm.
dpScheduleNode(dpScheduleNode *potential_parent, Joint *_last_joint, const fVec &_proc_costs, dpScheduleNode *_schedule_parent, int child_id, int _first_proc, int _last_proc, const joint_list &org_internal_joints, const p_joint_list &org_outer_joints)
RTC::ReturnCode_t ret(RTC::Local::ReturnCode_t r)
int Search(int _max_nodes=-1, int _max_goals=-1)
Dijkstra or A* search: find the node with the smallest cost.
double calc_min_subchain_cost(const p_joint_list &_outer_joints, joint_list &added_joints)
Base class for generic discrete search.
double add_to_child_side(Joint *cur, joint_list &added_joints, int *n_outer_parent_side, int *n_outer_child_side)
int ListAllInternalJoints(joint_list &all_internal)
static void get_all_joints(Joint *cur, joint_list &all_joints, joint_list &all_vjoints)
void SetStartNode(dpNode *_n)
Set the initial node for search.
void set(double *_d)
Sets all elements.
double calc_min_subchain_cost_sub(Joint *cur, const p_joint_list &_outer_joints, int *n_outer_parent_side, int *n_outer_child_side, joint_list &added_joints)
char * name
joint name (including the character name)
joint_list internal_joints[2]
void resize(int i)
Change the size.
pSubChain * default_schedule(pSubChain *p, Joint *j)
ofstream logfile("schedule.log")
Joint * brother
pointer to the brother joint
std::vector< class pJoint * > p_joint_list
Class for representing "handle"; two pJoint instances are attached to both sides of each joint...
int is_in(const joint_list &jlist, Joint *jnt)
fMat tran(const fMat &mat)
int is_goal()
Check if the state is goal.
void zero()
Creates a zero vector.
int create_child_nodes(dpNode **&nodes)
Create (potential) child nodes.
p_joint_list outer_joints
int NumJoint()
Total number of joints.
int in_subchain(pSubChain *sc, pLink *pl)
int split_internal_joints(Joint *_last_joint, const joint_list &org_internal_joints, joint_list &_internal_joints_0, joint_list &_internal_joints_1)
int Schedule()
Creates default schedule, which is optimized for serial computation.
Main class for forward dynamics computation.
The class for representing a joint.
Joint * real
pointer to the real (connected) joint; for closed chains.
int i_joint
index of the joint
double max_value()
Returns the maximum value.
dpScheduleNode * schedule_parent
int AutoSchedule(int max_procs)
Automatic scheduling for max_procs processors.
int set_outer_joints(pJoint *last_pjoint, const p_joint_list &org_outer_joints, p_joint_list &new_outer_joints)
dpNode * BestGoal(dpNode *ref=0)
Extract the goal with the smallest cost (if any).
void default_schedule_virtual(Joint *j)
Joint * parent
pointer to the parent joint
double add_to_parent_side(Joint *cur, joint_list &added_joints, int *n_outer_parent_side, int *n_outer_child_side)
void GetPJoint(Joint *_joint, pJoint *_pjoints[2])
double calc_single_joint_cost(int n_dof, int n_outer)
Matrix of generic size. The elements are stored in a one-dimensional array in row-major order...
Node for schedule tree; represents a partial chain.
dpScheduleNode * find_available_parent_sub(dpScheduleNode *cur, int target_depth, dpNode *cur_leaf, int &child_id)
Class for representing a single link in a schedule tree.