iCAx开思工具箱

标题: 自动装配简单的例子 [打印本页]

作者: wanxin9999    时间: 2005-5-8 15:02
标题: 自动装配简单的例子
嗯,五一劳动节,劳动了7天,比较光荣的完成了一点活。
我的娱乐项目就是在坛子里淘帖子了。
发现有很多同仁在在这里问道关于自动装配的问题。
我的课题在探索方法之初,我也做了一个很简单的例子。
拿出来献丑了,这都是难者不会,会者不难的东西吧。
希望给有疑问的一点有些启发,高手就不要笑话我了。
  
例子是做两个圆柱自动装配的例子。
先贴一下代码。
  
//打开第一个零件:
int CHANGE_add1_0_act_cb ( int dialog_id,
             void * client_data,
             UF_STYLER_item_value_type_p_t callback_data)
{
  char * part1="D:\\ugexam\\ugexam\\a.prt";
  char * refset_name1=NULL;
  double origin1[ 3 ]={0.0,0.0,0.0};
  char * instance_name1="a";
  double csys_matrix1[ 6 ]={1.0,0.0,0.0,0.0,1.0,0.0};
  
  int layer1=0;
  tag_t   instance1;
  int ret;
  char message[133];
  UF_PART_load_status_t error_status1;
  
  /* Make sure User Function is available. */   
  if ( UF_initialize() != 0)  
    return ( UF_UI_CB_CONTINUE_DIALOG );
  /* ---- Enter your callback code here ----- */
  //创建一个新的文件,再里面逐个增加零件,在产生配合条件进行装配
  //UF_UI_open_listing_window();
  
  UF_CALL(UF_PART_new(part_name1, UF_PART_ENGLISH, [$part))]  
  ret = UF_ASSEM_add_part_to_assembly (part, part1, refset_name1, instance_name1, origin1,
    csys_matrix1, layer1, [$instance1, &error_status1 )]
  if(ret != 0)
  {
    UF_get_fail_message(ret,message);
  }
  
  
  UF_terminate ();
  
    /* Callback acknowledged, do not terminate dialog */
    return (UF_UI_CB_CONTINUE_DIALOG);  
    
    /* or Callback acknowledged, terminate dialog.    */
    /* return ( UF_UI_CB_EXIT_DIALOG );               */
  
}
  
//在第一个零件中加入第二个零件。
int CHANGE_add2_1_act_cb ( int dialog_id,
             void * client_data,
             UF_STYLER_item_value_type_p_t callback_data)
{
  char * part2="D:\\ugexam\\ugexam\\b.prt";
  char * refset_name2=NULL;
  double origin2[ 3 ]={0.0,0.0,0.0};
  char * instance_name2="b";
  double csys_matrix2[ 6 ]={1.0,0.0,0.0,0.0,0.0,1.0};
  
  int layer2=0;
  tag_t   instance2;
  UF_PART_load_status_t error_status2;  
  
  /* Make sure User Function is available. */   
  if ( UF_initialize() != 0)  
    return ( UF_UI_CB_CONTINUE_DIALOG );
  
  /* ---- Enter your callback code here ----- */
  
  UF_CALL(UF_ASSEM_add_part_to_assembly (part, part2, refset_name2, instance_name2, origin2,
    csys_matrix2, layer2, [$instance2, &error_status2 ))]
  
  
     UF_terminate ();
  
    /* Callback acknowledged, do not terminate dialog */
    return (UF_UI_CB_CONTINUE_DIALOG);  
    
    /* or Callback acknowledged, terminate dialog.    */
    /* return ( UF_UI_CB_EXIT_DIALOG );               */
  
}
  
//实现自动装配
int CHANGE_action_3_act_cb ( int dialog_id,
             void * client_data,
             UF_STYLER_item_value_type_p_t callback_data)
{
    int ret;
  char * name1="ENDFACE1";
  char * name2="ENDFACE2";
  char * name3="CYCLE1";
  char * name4="CYCLE2";
  tag_t first_plan,second_plan,cylinder_face1,cylinder_face2;
  
  tag_t from_part_occ;
  tag_t to_part_occ;
  tag_t from_part_ins;
  tag_t to_part_ins;
  logical is_occ;  
  
  tag_t cylinder_from_part_occ;
  tag_t cylinder_to_part_occ;
  tag_t cylinder_from_part_ins;
  tag_t cylinder_to_part_ins;
  //logical cylinder_is_occ;
  
  //提示所显示的实例的名称
  char part_name[ 256 + 1 ];
  char refset_name[ 30 + 1 ];
  char instance_name[ 30 + 1 ];
  double origin[ 3 ];
  double csys_matrix[ 9 ];
  double transform[ 4 ][ 4 ] ;
  char message[133];
  //======
  //char tt[10];
  //======
  UF_ASSEM_mc_status_t status;
  UF_ASSEM_mc_structure_state_t struct_status;
  UF_ASSEM_dof_t dof;
  UF_ASSEM_mating_condition_t ftf;
  //UF_ASSEM_mating_condition_p_t mc_data;
  
  /* Make sure User Function is available. */   
     if ( UF_initialize() != 0)  
          return ( UF_UI_CB_CONTINUE_DIALOG );
  
     /* ---- Enter your callback code here ----- */
   first_plan=NULL_TAG;
   second_plan=NULL_TAG;
   cylinder_face1=NULL_TAG;
   cylinder_face2=NULL_TAG;
  
   UF_OBJ_cycle_by_name (name1, [$first_plan)]
   UF_OBJ_cycle_by_name (name2, [$second_plan)]
    // UF_DISP_set_highlight(first_plan,1);
  // UF_DISP_set_highlight(second_plan,1);
    
   UF_OBJ_cycle_by_name (name3, [$cylinder_face1)]
   UF_OBJ_cycle_by_name (name4, [$cylinder_face2)]
  
   //====================================================================
   //第一种匹配条件:选取UF_ASSEM_v16_mate和UF_ASSEM_planar_face进行匹配
   //====================================================================
  
///////////////////////////第一个平面//////////////////////
   //UF_MODL_ask_face_data (first_plan,[$type,point,dir,box,&radius,&rad_data,&norm_dir)]
   ret=UF_ASSEM_ask_parent_component (first_plan, [$from_part_occ)]//获取父标志
   is_occ=UF_ASSEM_is_occurrence(from_part_occ);//确定父标志类型
                         //TRUE = if object occurrence or a part occurrence.
                         //FALSE = if object is a prototype object
   from_part_ins=UF_ASSEM_ask_inst_of_part_occ (from_part_occ);//获取part occurrence中instance的tag
   ret=UF_ASSEM_ask_component_data (from_part_occ,part_name,refset_name,instance_name,  
     origin, csys_matrix, transform);
  
///////////////////////////第二个平面//////////////////////
   ret=UF_ASSEM_ask_parent_component (second_plan, [$to_part_occ)]
   to_part_ins=UF_ASSEM_ask_inst_of_part_occ (to_part_occ);
   ret=UF_ASSEM_ask_component_data (to_part_occ,part_name,refset_name,instance_name,  
     origin, csys_matrix, transform);
  
   //========================================================================
   //第二种匹配条件:选取UF_ASSEM_center和UF_ASSEM_cylindrical_face进行匹配
   //========================================================================
  
   ///////////////////////////第一个圆柱面//////////////////////
   ret=UF_ASSEM_ask_parent_component (cylinder_face1, [$cylinder_from_part_occ)]
   cylinder_to_part_ins=UF_ASSEM_ask_inst_of_part_occ (cylinder_from_part_occ);
   ret=UF_ASSEM_ask_component_data (cylinder_to_part_occ,part_name,refset_name,instance_name,  
     origin, csys_matrix, transform);
  
   ///////////////////////////第二个圆柱面//////////////////////
   ret=UF_ASSEM_ask_parent_component (cylinder_face2, [$cylinder_to_part_occ)]
   cylinder_to_part_ins=UF_ASSEM_ask_inst_of_part_occ (cylinder_to_part_occ);
   ret=UF_ASSEM_ask_component_data (cylinder_to_part_occ,part_name,refset_name,instance_name,  
     origin, csys_matrix, transform);
  
     //构造配合关系
  //=======================
  UF_ASSEM_init_mc ([$ftf)]  //初始化
  //=======================
  ftf.mated_object=from_part_ins;
  ftf.name=NULL;
  ftf.user_name=FALSE;
  ftf.constraints[0].from_status = UF_ASSEM_ok;
  ftf.constraints[0].to_status = UF_ASSEM_ok;
  ftf.constraints[0].mate_type = UF_ASSEM_v16_mate;
  ftf.constraints[0].from_type = UF_ASSEM_planar_face;
  ftf.constraints[0].to_type = UF_ASSEM_planar_face;
  ftf.constraints[0].from = UF_ASSEM_ask_prototype_of_occ (first_plan);
  ftf.constraints[0].from_part_occ = from_part_occ;
  ftf.constraints[0].to = UF_ASSEM_ask_prototype_of_occ (second_plan);
  ftf.constraints[0].to_part_occ = to_part_occ;
  ftf.constraints[0].offset = NULL_TAG;
  ftf.constraints[0].name = "face to face";
  ftf.constraints[0].user_name = TRUE;
  //**********************************************
  ftf.constraints[1].from_status = UF_ASSEM_ok;
  ftf.constraints[1].to_status = UF_ASSEM_ok;
  ftf.constraints[1].mate_type = UF_ASSEM_center;  //选择同轴匹配类型
  ftf.constraints[1].from_type = UF_ASSEM_cylindrical_face;//定义为选取圆周面匹配
  ftf.constraints[1].to_type = UF_ASSEM_cylindrical_face;
  ftf.constraints[1].from = UF_ASSEM_ask_prototype_of_occ (cylinder_face1);//获取选取对象原型的tag
  ftf.constraints[1].from_part_occ = cylinder_from_part_occ;  //匹配对象的part occurrence的tag
  ftf.constraints[1].to = UF_ASSEM_ask_prototype_of_occ (cylinder_face2);
  ftf.constraints[1].to_part_occ = cylinder_to_part_occ;
  ftf.constraints[1].offset = NULL_TAG;  //定义距离,可利用表达式控制
  ftf.constraints[1].name = "center to center";
  ftf.constraints[1].user_name = TRUE;
  ftf.constraints[1].sub_type = UF_ASSEM_center_1_to_1;//选取角度和同轴对齐的适当子类型
  //************************************************
  ftf.num_constraints=2;
  ftf.suppressed=FALSE;
  
  ret=UF_ASSEM_solve_mc ([$ftf, &status, &dof, transform)]//条件计算
  UF_get_fail_message (ret,message);
  
  if (ret==0||status==UF_ASSEM_mc_solved)
  {
    ret=UF_ASSEM_apply_mc_data ([$ftf, &struct_status, &status )]//执行匹配
    UF_DISP_refresh();
    UF_MODL_update();
  }
  
     UF_terminate ();
  
    /* Callback acknowledged, do not terminate dialog */
    return (UF_UI_CB_CONTINUE_DIALOG);  
    
    /* or Callback acknowledged, terminate dialog.    */
    /* return ( UF_UI_CB_EXIT_DIALOG );               */
  
}
  
嗯,很早以前做的例子,很久没试了。
发帖有点不大灵光,先发了。有问题及时告诉一声,我会赶紧改的。
作者: wanxin9999    时间: 2005-5-8 15:23
这是uistyler设计的简单对话框界面
作者: wanxin9999    时间: 2005-5-8 15:25
这是在打开第一个圆柱之后,增加第二个圆柱
装配前的图。
作者: wanxin9999    时间: 2005-5-8 15:26
嗯,点击按钮,实现自动装配后的图
作者: mizzle    时间: 2005-5-8 15:28
不错,是在nx3上作的?
我想问一下,nx3在函数里有没有比nx1多了内容?
作者: wanxin9999    时间: 2005-5-8 15:30
值得一提的是,我用的办法,实际上,是给指定的零件,也就我这里的a.prt和b.prt零件,做了一些属性上的操作。
  
我分别打开两个圆柱,给指定要实现自动装配的对象,定义了名称属性。
在装配的时候,通过名称属性,查找相应对象的tag值。
有了tag值,进一步操作,大家可以参照上面的代码。
  
如果有什么问题欢迎大家讨论。
以及批评指正。
作者: wanxin9999    时间: 2005-5-8 15:34
我用过ug18,然后直接到nx2.0,nx3.0 没有用过nx1.0
  
我只有一点感性的认识,觉得nx3.0的界面以及操作方面,显得更加的友好。
  
希望别的用过的同志们跟mizzle说一下。
作者: mxsfyu    时间: 2005-5-8 18:11
就开放的OpenAPI函数,NX3.0比NX1.0要多点,比方说UF_VIEW_create_view_set//可以用来创建视图的
History
This routine is originally created in release NX3.0
这个函数只是在UG3.0中才出现,以前是用调用布局函数间接实现的
  
大部分函数后面的History,中都标明了公布时间的,以及所作的修改或替换。
作者: miraculous    时间: 2005-5-9 18:17
不错不错,写得挺清楚,又有些收获
作者: zwg_xl    时间: 2005-5-10 17:06
代码不完整,结果出不来!能将完整的程序贴上来吗?
作者: liberty000    时间: 2005-5-10 21:43
zwg_xl wrote:
代码不完整,结果出不来!能将完整的程序贴上来吗?

  
已经讲的很清楚了,老大,最少是我见过的讲的最清楚的资料。
作者: wanxin9999    时间: 2005-5-11 15:36
谢谢开心一笑的理解。
对了,楼上的能不能把问题说的清楚一点?
没有结果的事情实在是太多了。
我觉得代码不是最重要的,
一定要明白思路,对巴?
其次是问题,究竟有什么问题?原因是什么?
你说呢?
作者: zwg_xl    时间: 2005-5-12 11:40
请教楼主,我试了几天,就是没有结果,我想问:
    圆柱端面("ENDFACE1"和ENDFACE2")的tag是如何传递给参数first_plan和 second_plan的?也就是说怎么获得圆柱端面和侧面的标识?是通过函数UF_OBJ_cycle_by_name (name1, &first_plan)吗?UF_OBJ_cycle_by_name 功能是什么?
    ENDFACE1和CYCLE1这两个名称是自己给的还是UG中默认的圆柱端面和侧面名称?
帮帮忙!急切盼望楼主答复。
     
   
作者: wanxin9999    时间: 2005-5-12 20:38
你说的对阿。
  
代码里面有用你说的这个函数的。
功能是什么,帮助文档里有的,如果你没有找到,我回头贴给你。
  
怎么会是默认的呢?呵呵,我在后面的帖子中说过了,我是我“做了一些属性上的操作”。也就是你说的自己给她加上上了名称属性。
  
嗯,你有这样的想法,应该去试一试先的。
还有,看帮助文档要耐心。
嗯,这是一些建议,希望你不要嫌我罗嗦。
  
好了,有什么问题,尽管提。
作者: zwg_xl    时间: 2005-5-15 17:34
楼主,上面的代码,零件加载成功,可到装配时还是结果出不来,我检查了n遍,还是装不到一起,都快半个月了,还没解决!我该怎么办????
作者: wanxin9999    时间: 2005-5-20 10:09
上次看到楼上的讲到遇到.men文件以及菜单还有调用的问题。
上次没有细看,这次过来看,发现贴子没了。
看来楼上的已经解决了这些问题。
  
嗯,楼上的也可以把你遇到问题之后怎么解决的经验介绍给大家哦。
作者: yanda2008    时间: 2005-5-20 20:27
请教楼主:
我是一名初学者,且只是用于毕业设计,没有系统的学习过。
请问楼主怎样才能定义了名称属性,在装配的时候,
通过名称属性,查找相应对象的tag值。
还有我按你的程序写上了怎么有如下两处警告,
warning C4101: 'cylinder_from_part_ins' : unreferenced local variable
warning C4700: local variable 'cylinder_to_part_occ' used without having been initialized
零件加载成功,可到装配时还是结果出不来!这是怎么回事呢?急切盼望答复!!
能不能将全部的代码发给我呢?
邮箱是:yanda2009@sina.com.cn
只用于毕业设计的参考,别不他图!
时间急促,月底就要答辩,望能尽快答应!将不胜感激!
谢谢!

作者: yanda2008    时间: 2005-5-20 20:47
快点回好吗?
求求了!
作者: yanda2008    时间: 2005-5-20 20:48
求助大侠们解难
拜托了!
作者: zwg_xl    时间: 2005-5-22 13:27
wanxin9999 wrote:
上次看到楼上的讲到遇到.men文件以及菜单还有调用的问题。  
  上次没有细看,这次过来看,发现贴子没了。  
  看来楼上的已经解决了这些问题。  
  
  嗯,楼上的也可以把你遇到问题之后怎么解决的经验介绍给大家哦。

没错,已经解决了,具体你可以上ugopenmen兄的网站下载一片非常有用的关于用户菜单制作的文章看看,网址好像是www.ugopen.com  。 还有,上面的例子代码肯定是调不出来的,但重要的是他的思路,我将由名称遍历圆柱底面和侧面变成直接从界面上交互选择后,就成功了!
作者: wanxin9999    时间: 2005-5-22 19:09
en,关于名称属性的定义:
首先,请找到“类选择器”的工具条,见下图。
确定你选择的是一般对象还是,特征……
然后你就可以选了阿。
  
比如你选择的是一个面,那么他是一般的对象。
如果是一个回转的特征,那么他是一个特征。
然后你选择好的对象上,单击右键。
在弹出菜单中,选择属性。
然后在名称栏目下键入你取得名称就好了。
当然记得保存哦。
作者: yanda2008    时间: 2005-5-24 07:40
楼主
  
有没有函数来调类(选择)构造器!
作者: mizzle    时间: 2005-5-24 09:12
UF_UI_select_class等这些函数是不是你要的选择函数呢
作者: mizzle    时间: 2005-5-25 15:59
搂主上面讲了两个圆柱面的自动装配,有没有做过,就像ug装配里的,让一个圆柱面同一个圆去配合,就是建立一个part文件后,然后再上面直接画一个圆,然后再加入一个圆柱的时候,让他们配合,这样的话to_part_occ
有该怎么定义!
作者: wanxin9999    时间: 2005-5-25 17:20
恩,今天还在和师弟讨论这个装配的问题。
他提到,在solidworks中可以之间将一个螺钉拖到孔处,他就可以直接配合。
恩,你是不是也要实现类似的功能?
  
从我的感觉应该是可以的,但是这里不是简单的几个函数可以完成的。
本来装配中的那些函数中都是一堆结构体。你怎么去判断,怎么去描述他,涉及到很多函数的协同工作,我个人觉得,
还有概念一定要很清楚才行。
  
en ,愿意和大家进一步讨论,但是,问题最好范围更小一点。你说是吧?
作者: wanxin9999    时间: 2005-5-25 17:22
还有楼上的同学阿,有些工作,不一定非要用函数去做他的。
如果可以直接用他的工具做一些先前的预处理,能使问题简单明了的情况,
就千万不要总是编程去做,不能简化问题,甚至出很多麻烦。
作者: mizzle    时间: 2005-5-26 08:29
呵呵,这个问题已经解决了,其实很简单,只不过通过你例子中的,无法得到在建立的root part里的圆的occurence,其实只要得到,work part的occurence就可以了,因为画的圆本来就是在work part里画的吗
作者: wanneng2005    时间: 2005-5-27 16:29
我最近也正在搞装配这部分开发,看到这种好贴,我发自肺腑的感谢楼主,希望能和楼主在CAD方面有更多的交流!
作者: wanxin9999    时间: 2005-5-27 16:53
嘿嘿,楼上的是我的托儿。
他是做NX OPEN for.net的。
大家在这方面有问题的不要放过他哦
他人很好的!
  
对于,自动装配,我想大家侧重点各有不同,
估计有人着意解决的是在装配中对象的tag值动态分配的问题。
  
而我总觉得,上面这种方法,对于概念一定要很清楚。
所以,是否可以从---约束方面,来解决这个问题?
作者: wanneng2005    时间: 2005-5-27 17:02
唉,家家都有一本难念的经呀!
作者: wanneng2005    时间: 2005-5-27 20:32
楼主的帖子对我帮助很大,真的谢谢呀!
作者: lenovonuaa    时间: 2005-5-29 19:27
不错的帖子,受益
作者: obana    时间: 2005-11-10 02:24
看了诸位的回帖,收获不小。随之而来的问题就是自动装配到底可否实现,的确,完全靠程序不可行,那么在建模过程是不是可以采取一些措施来帮助实现自动装配?
        我现在在做一个协同装配的系统,目前主攻约束关系建模,我想如果把这个模型建好了,自动装配实现的基础也就有了。
        剩下的,就是编程实现的问题了,我照着lz的方法做了一遍,零件加进去了,装配没实现。UG OPEM API一书里是用交互的方法实现装配的,楼上也有人证明可行。lz的方法为我们提供了一些思路,但为什么用遍历的方法获取不了平面和圆柱面呢?
作者: murongjun    时间: 2006-2-6 16:59
受益非浅,谢谢!!
作者: murongjun    时间: 2006-2-14 18:57
标题: 自动装配
如果char * name1="ENDFACE1"是定义在工作零件里(也就是说第一个圆柱是工作零件),使用UF_OBJ_cycle_by_name (name1, [$first_plan)] 得到的first_plan好像不是OCC(事件)而是原型,此时用UF_ASSEM_ask_parent_component (first_plan, [$from_part_occ)]就会出错.请各位指点,谢谢!!
作者: zhoujunbo830    时间: 2007-9-15 11:09
标题: 求助
太感谢了!!
作者: zhoujunbo830    时间: 2007-9-15 18:43
我想问问可以用函数去遍历他后找到那四个面吗??
如何解决!!!
作者: chengzhongcai    时间: 2007-9-15 19:29
b不错,我是个新手,请问有没有些教程类的啊  ,让人一看就知道你是怎么做出来的
作者: 张少杰    时间: 2010-11-21 17:13
谢谢楼主共享
作者: QYW0735    时间: 2011-2-12 14:07
顶!!!!!!!
看看再说
作者: zfs_007    时间: 2011-3-8 20:06
1#  内容不错。但是还有些地方弄不清楚。




欢迎光临 iCAx开思工具箱 (https://t.icax.org/) Powered by Discuz! X3.3