Webots仿真超市补货机器人

webots仿真超市自动补货机器人

  • 选题要求
  • 基于webots平台下机器人选型与模型搭建
    • 机器人结构选型设计
      • 机器臂结构设计
    • 机器人传感器设计
      • 电机力传感:
      • 视觉传感:
      • 罗盘及GPS:
    • 世界搭建
  • 机器人控制器设计与实现
  • 整体项目开法
    • 状态机代码流程::
    • 视觉处理功能及抓取功能
    • 避障功能
  • 总结

选题要求

功能需求:
基本需求:机器人需要从起点处去往,从平台上取得货物,并将其放在指定货架的空货窗内,最后返回起点
拓展需求:两台(或两台以上)机器人同时进行补货操作,可以一次取多件货物
在这里插入图片描述 图2 超市补货机器人升级版场地示意图
【基本任务】单机器人补货操作
机器人需要在仓库的平台上取得货物,并将其放在指定货架的空货窗内,每放置正确1件货物得10分,放错货架或放入非空的货窗,则扣5分。
【挑战任务】多机器人协作
两台(或两台以上)机器人同时进行补货操作(需要考虑避障;可以一次取多件货物),参加挑战任务的项目组有额外的加分。
性能分析:
路径规划:两台机器人在协同工作时,能找到一条从起点到终点适当的运动路径,使机器人在运动过程中能安全、无碰撞地绕过所有障碍物,若机器人规划路径产生冲突,其中一台机器人应及时避让
机器视觉:机器人能够准确识别分类货物,同时识别货架,判断货架是否存放有货物,能为货物正确匹配货架

抓取及路径最优化:机器手设计部分,采用较为简单的二连杆或者四连杆结构,对货物的起落进行精确控制。
约束及性能评判
约束明确:由于实物搭接的不便,本项目采用webots进行机器人建模与仿真模拟
1.由于图像处理算法过于复杂,采用现成的recognition API实现对于相关代码的省略化,使仿真专注于建模与运动算法的开发
2.机器人具体结构建模,考虑利用world搭建里现有的E-puck机器人为基础,进行进一步的搭接
3.对于系统某些参数的设定与调整,我们尽量采用world里现有的进行调用或者模仿,避免出现调参消耗大量时间

基于webots平台下机器人选型与模型搭建

机器人结构选型设计

移动方案:采用四轮机器人模型,轮子使用例程youbot的麦克纳姆轮

抓取方案:以例程pioneer3_gripper中的机器爪模块为原型进行修改

在这里插入图片描述而经过项目的推进与设计,我们还在已有基础上,搭载了红外传感器,以进行避障功能,结构如下:
在这里插入图片描述
具体细节

麦克纳姆轮:麦克纳姆轮技术的全方位运动设备可以实现前行、横移、斜行、旋转及其组合等运动方式。此处采用youbot中的proto文件进行直接引入,简化操作。
在这里插入图片描述

机器臂结构设计

原版pioneer3的gripper太小,不能满足取货放货的需求,因此考虑调节机器臂的比例,再对其进行组合
在这里插入图片描述

机器人传感器设计

电机力传感:

在这里插入图片描述机器爪gripper不能通过代码后台直接调节手抓开合大小抓取物体,因此可以考虑在机械抓上加装力传感器,反馈电机转速来逐渐抓紧物体

视觉传感:

机器人主体上使用前后置两个摄像头实时反馈机器人前后方图像,机械臂上采用一个顶部摄像头反馈机械臂位置。
在这里插入图片描述

罗盘及GPS:

机器人使用一个gps反馈机器人位置,和一个罗盘反馈机器人姿态。在这里插入图片描述
对于避障环节,我们初步考虑的是,不去采用epuck机器人类似的车身八个的红外传感器进行避障,
原因是,觉得在利用了罗盘和GPS,且在固定空间下运作的情况下,利用sensor进行避障处理会更加麻烦(之后如果采用多机器人协作,可以适当考虑利用传感器进行进一步保底设计)。

但经过讨论,在项目最终进行阶段,还是考虑采用epuck机器人类似的车身红外传感进行避障功能的实现。

在这里插入图片描述

世界搭建

具体细节不过多阐述,可以参考官网学习文档中提供的tutorial,此处需要注意的细节是,在构建货架等非透视项目时,要在node里勾选,不然在视觉处理中,会在扫描第一列货架时,后排的货物会出现重叠覆盖,导致不能准确抓取。

机器人控制器设计与实现

webots采用的为其自带的c++,所以状态机的设置主要通过构建枚举量进行,同时也方便状态之间进行跳转

整体项目开法

状态机代码流程::

  1. Initial Pose

整个流程,从最开始的Init_Pose开始,对所有机构进行初始化,同时,利用set_posture,将机器人置于第一个顶点,即fixed_posture_findempty的第一行元素,此时车尾对着货架, 顶部摄像头调用Find_Empty进行空货架识别,若调用失败,则货架+1,巡航点下标+1,设置fin_target_posture
并进入前往下一个货架状态

  1. Recognize_Empty

在此状态,判断是否到达下一个货架,若到达,则状态重新转为Recognize_Empty进行空货架识别,,若未到,则巡航点下标+1,直到其与所设置的四个空货架定位点相等,系统跳转至Recognize_Empty.

  1. up_to_top & return_initial

若摄像头识别到了空货架,则状态转至环绕取货堆运动,但是此时不方便直接开始绕取货堆运动,考虑利用一新状态up_to_top使得所有位置运动到最上层(利用set_posture()的第二个参数修改成-5),再进入下一状态return_initial,写回归起点,若未回到(1.05,1.05,2*PI)的位姿,则利用
double initial进行更进一步地从最顶层往右侧返回初始点的操作

  1. Arround_Moving

若判断回到起点,则转入下一状态Arround_Moving,写环绕取货堆进行取货操作。
在Arround_Moving状态中,若没有对准物体,则率先判断物体是否已经到达上个状态结束时的位置(即初始位置(1.05,1.05,2*PI)),若未到达,则移动至该位置,到达则进行接下操作,令gp_travel_points_sum累加,并打印当前货架信息,通过遍历整个取货路径的位姿,直至Find_Goods到达指定位置,使其达到“恰好”状态若恰好在当前位置面对物品则转入下一阶段Grab_Item进行物体抓取。通过函数Aim_and_Grasp(),进行对准与抓取操作,若操作成功,返回真值,进行状态的进一步推进,即进入Back_Moving状态。

  1. Back_Moving

Back_Moving状态里,先判断物体是否已经到达上个状态结束时的位置(即待取货物位置的机器人姿态),若未到达,则移动至该位置,到达则进行接下操作,即令下标gp_Travel_Point_Index不断累加,进行巡航,直至到达起点,即gp_Travel_Point_Index等于11时,进入下一状态back_to_shelf
若此时的fin_target_posture为之前寻找到的空货架的定点的位置,则整个状态转移到TurnBack_To_LoadItem,进行转身装货过程,
若未到达,则利用一个temp作为临时变量,在每一次进入时进行自增操作,直至其到达原定货架位置。

之后进入TurnBack_To_LoadItem,通过gps计算和上货点的相对位移,通过compass计算姿态,对load_target_posture进行赋值,
最后转入上货状态 Item_Loading进行上货操作,通过按着最开始设置的步长进行步进,达到稳定上货的目的,在上完货之后,控制机器臂手抓开合与升降,对状态再次进行更换,重新回Init_Pose

注意:Travel_Point_Index下标通过整个货架巡航轨迹,一直与fixed_posture_findempty的四个定点匹配,因此在最后填充完货物后,
进行下一个货架的检索并不受影响。

视觉处理功能及抓取功能

//前部摄像头校准并抓取
bool Aim_and_Grasp(int *grasp_state, WbDeviceTag camera, int objectID)
{int number_of_objects = wb_camera_recognition_get_number_of_objects(camera);const WbCameraRecognitionObject *objects = wb_camera_recognition_get_objects(camera);for (int i = 0; i < number_of_objects; ++i){if (objects[i].id == objectID) //自左往右自下往上搜寻第一个物体{if (*grasp_state == 0) //调整位置{//调整高度,放置抓取错误,出现world is too complex等报错if (!strcmp("cereal box red", objects[i].model) || !strcmp("cereal box", objects[i].model))lift(height = 0.05);else if (!strcmp("water bottle", objects[i].model))lift(height = 0.080);else lift(height = 0.01);moveFingers(width = objects[i].size[0] / 1.5);get_gps_values(gps_values);get_compass_angle(&compass_angle);double grasp_target_posture[3];double grasp_dis_set = Grasp_dis_set[name2index(objects[i].model)];grasp_target_posture[0] = (gps_values[0] - sin(compass_angle) * objects[i].position[0] + cos(compass_angle) * (objects[i].position[2] -  grasp_dis_set) * 0.6);grasp_target_posture[1] = gps_values[1] - cos(compass_angle) * objects[i].position[0] - sin(compass_angle) * (objects[i].position[2] -  grasp_dis_set) * 0.6;grasp_target_posture[2] = compass_angle;Moveto_CertainPoint1(grasp_target_posture, 0.005);double grasp_threshold = 0.002;if (fabs(objects[i].position[0]) < grasp_threshold && fabs(objects[i].position[2] - grasp_dis_set) < grasp_threshold){*grasp_state += 1;printf("抓手已对准\n");base_reset();printf("物体大小: %lf %lf\n", objects[i].size[0], objects[i].size[1]);moveFingers(width = objects[i].size[0] / 2);wb_robot_step(30000 / TIME_STEP);}}else if (*grasp_state == 1) //抓{double grasp_force_threshold = 83.0;if (wb_motor_get_force_feedback(gripper_motors[1]) > -grasp_force_threshold)moveFingers(width -= 0.0003); //步进else{wb_robot_step(30000 / TIME_STEP); if (wb_motor_get_force_feedback(gripper_motors[1]) <= -grasp_force_threshold){printf("爪宽:%.4f\n", width);*grasp_state += 1;printf("GoodsonShelf[%d][%d] need %s\n", CurrentShelf, TargetIndex, index2name(TargetGood));if (!strcmp("water bottle", objects[i].model))//水杯特殊高度lift(height = 0.12);else if (!strcmp("cereal box red", objects[i].model))//红大盒子特殊高度lift(height = 0.50);else if (!strcmp("cereal box", objects[i].model))lift(height = 0.30);else if (TargetIndex < 8)lift(height = 0.05);else if (CurrentShelf % 2 == 0) //矮柜0.23lift(height = 0.23);else if (CurrentShelf % 2 == 1) //高柜0.43lift(height = 0.43);printf("升降臂已举起height = %.3f\n", height);wb_robot_step(10000 / TIME_STEP);}}}else if (*grasp_state == 2) //举{return true;}break;}}return false;
}//寻找空货架 给四个定点GPS 摄像头看四面墙 返回货架位置和一个商品种类
bool Find_Empty(WbDeviceTag camera)
{int number_of_objects = wb_camera_recognition_get_number_of_objects(camera);// printf("识别到 %d 个物体.\n", number_of_objects);const WbCameraRecognitionObject *objects = wb_camera_recognition_get_objects(camera);int GoodsonShelf[4][16];      //货架上的物品ID号 先下后上 先左后右for (int i = 0; i < 4; i++)for (int j = 0; j < 16; j++)GoodsonShelf[i][j] = -1;//不知道为啥写在定义的时候不成功for (int i = 0; i < number_of_objects; ++i){int Shelfx = max(0, floor((objects[i].position[0] + 0.84) * 4.17 + 0.5)); //左右 平均间隔0.24(架子宽度0.25)右移后对应一个系数 四舍五入int Shelfy = (objects[i].position[1] < -0.2) ? 0 : 1;             //上下层 -0.20  为上下分界GoodsonShelf[CurrentShelf][Shelfy * 8 + Shelfx] = name2index(objects[i].model);printf(" 物体 %s 对应编号 %d 写入[%d] 写入编号为%d\n", objects[i].model, name2index(objects[i].model), Shelfy * 8 + Shelfx, GoodsonShelf[CurrentShelf][Shelfy * 8 + Shelfx]);}//检测完毕 判断下一个要取的货物类型int Empty_Flag = 0;for (int j = 0; j < 16; j++)printf("GoodsonShelf[%d][%d] = %d\n", CurrentShelf, j, GoodsonShelf[CurrentShelf][j]);for (int j = 0; j < 16; j++){// if (strlen(GoodsonShelf[CurrentShelf][j]) == 0) // 这种判断可能会crash//   Empty_Flag = 1;if (GoodsonShelf[CurrentShelf][j] == -1){Empty_Flag = 1;TargetIndex = j;//寻找邻近货物 判断应该取的货物类型//直接覆盖 假装已经放上去了int TargetFloor = 0;if (j > 7)TargetFloor += 8; //层数无关if (j % 8 < 4)for (int k = 0; k < 8; k++)//从左往右{if (GoodsonShelf[CurrentShelf][TargetFloor + k] != -1){// strcpy(TargetGood, GoodsonShelf[CurrentShelf][TargetFloor + k]);TargetGood = GoodsonShelf[CurrentShelf][TargetFloor + k];break;}}elsefor (int k = 7; k >= 0; k--)//从右往左{if (GoodsonShelf[CurrentShelf][TargetFloor + k] != -1){// strcpy(TargetGood, GoodsonShelf[CurrentShelf][TargetFloor + k]);TargetGood = GoodsonShelf[CurrentShelf][TargetFloor + k];break;}}printf("GoodsonShelf[%d][%d] need %s\n", CurrentShelf, j, index2name(TargetGood));break;}}if (Empty_Flag)return true;elsereturn false;
}

避障功能

//GPS运动到指定位姿,返回bool值反馈是否到达,默认精度0.05
bool Moveto_CertainPoint1(double fin_posture[], double reach_precision)
{if (targetdist_reached(fin_posture, reach_precision) && targetpos_reached(fin_posture, reach_precision)){// printf("到达目标位置!\n");// base_reset();return true;}else{caculate_tmp_target(tmp_target_posture, fin_posture);base_goto_set_target(tmp_target_posture[0], tmp_target_posture[1], tmp_target_posture[2]);// printf("Target:%s\n", point_name[point_index]);// printf("initial target: %.3f  %.3f  %.3f\n", initial_posture[0], initial_posture[1], initial_posture[2]);// printf("tmp target: %.3f  %.3f  %.3f\n", tmp_target_posture[0], tmp_target_posture[1], tmp_target_posture[2]);// printf("final target: %.3f  %.3f  %.3f\n\n", fin_posture[0], fin_posture[1], fin_posture[2]);base_goto_run();return false;}
}
bool Moveto_CertainPoint(double fin_posture[], double reach_precision)
{if (targetdist_reached(fin_posture, reach_precision) && targetpos_reached(fin_posture, reach_precision)){// printf("到达目标位置!\n");// base_reset();return true;}else{int i, bizhang_flag;double ds[10];bizhang_flag = 0;for (i = 0; i < 10; i++){ds[i] = wb_distance_sensor_get_value(distanse_sensor[i]);if ((i == 0 || i == 7 ) && main_state != Arround_Moving && main_state != Back_Moving){ds[i] = ds[i] * 1;}if ((i == 8 || i == 9) && (main_state == Arround_Moving || main_state == Back_Moving || main_state == RunTo_NextShelf)){ds[i] =  ds[i] * 0.4;}if (ds[i] < 0)ds[i] = 0;if (ds[i] < 350){bizhang_flag = 1;}}if (bizhang_flag == 1 && main_state != Grab_Item && main_state != Item_Loading && main_state != RunTo_NextShelf && main_state != TurnBack_To_LoadItem){//printf("正在避障\n");bizhang(fin_posture, ds);}else{caculate_tmp_target(tmp_target_posture, fin_posture);base_goto_set_target(tmp_target_posture[0], tmp_target_posture[1], tmp_target_posture[2]);}// printf("Target:%s\n", point_name[point_index]);// printf("initial target: %.3f  %.3f  %.3f\n", initial_posture[0], initial_posture[1], initial_posture[2]);// printf("tmp target: %.3f  %.3f  %.3f\n", tmp_target_posture[0], tmp_target_posture[1], tmp_target_posture[2]);// printf("final target: %.3f  %.3f  %.3f\n\n", fin_posture[0], fin_posture[1], fin_posture[2]);base_goto_run();return false;}
}void bizhang(double fin_posture[], double ds[])
{	//最小的ds,当成为机器人移动方向//base_reset();int i;double move_direction_x = 0;double move_direction_y = 0;double move_time = 0.5;for (i = 0; i < 10; i++){move_direction_x = move_direction_x + (1000 - ds[i]) / 1000 * bizhang_x[i];move_direction_y = move_direction_y + (1000 - ds[i]) / 1000 * bizhang_y[i];}if (move_direction_y < 0){base_backwards();passive_wait(abs(move_direction_y)* move_time);}else{base_forwards();passive_wait(abs(move_direction_y) * move_time);}if (move_direction_x < 0){base_strafe_left();passive_wait(abs(move_direction_x) * move_time);}else{base_strafe_right();passive_wait(abs(move_direction_x) * move_time);}/*if (ds[8] < min_distance || ds[9] < min_distance){if (ds[0] > ds[7]){base_strafe_left();passive_wait(0.5 * move_time);base_backwards();passive_wait(0.5 * move_time);}else{base_strafe_right();passive_wait(0.5 * move_time);base_backwards();passive_wait(0.5 * move_time);}}else if (ds[0] < min_distance || ds[1] < min_distance){base_strafe_right();passive_wait(0.5 * move_time);base_backwards();passive_wait(0.5 * move_time);}else if (ds[2] < min_distance || ds[3] < min_distance){base_strafe_right();passive_wait(0.5 * move_time);base_forwards();passive_wait(0.5 * move_time);}else if (ds[4] < min_distance || ds[5] < min_distance){base_strafe_left();passive_wait(0.5 * move_time);base_forwards();passive_wait(0.5 * move_time);}else if (ds[6] < min_distance || ds[7] < min_distance){base_strafe_left();passive_wait(0.5 * move_time);base_backwards();passive_wait(0.5 * move_time);}else{}*/
}

总结

本仿真完成参考了往届学长的思路流程并在其中调整了货堆摆放位置、修改了视觉处理及循迹策略,同时HIA增加了障碍物与避障功能等一系列改进。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/31663.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SAP RETAIL 如何确定自动补货触发的单据类型

SAP RETAIL 如何确定自动补货触发的单据类型 在SAP系统里执行事务代码WRP1R, 执行&#xff0c; SAP系统触发了一个采购订单&#xff0c;单据号是4500000696。如下图&#xff1a; 我们发现该补货程序自动创建出来的PO单据类型是NB。 问题来了&#xff1a;如果希望自动补货触发的…

SAP RETAIL 补货类型RF之初探 I

SAP RETAIL 补货类型RF之初探 I SAP RETAIL系统里&#xff0c;商品主数据里MRP Type字段值如果是RF (Replenish with dyn.TargetStock &#xff09;, 则系统在自动补货的时候&#xff0c;会自动动态计算应该补货的数量。跟MRP type RP不同的是&#xff0c;RP的时候则系统仅仅会…

SAP RETAIL 商品主数据里影响自动补货结果的几个参数 I

SAP RETAIL 商品主数据里影响自动补货结果的几个参数 I SAP零售行业解决方案里有自动补货的功能&#xff0c;能支持业务部门的补货场景。因为SAP RETAIL里基本不再RUN MRP&#xff0c;其补货功能是通过事务代码WRP1或者WRP1R来实现的。通过运行这些事务代码&#xff0c;SAP系统…

新版语音直播社交APP源码 多人连麦聊天/双端APP源代码 附编译说明

功能介绍&#xff1a; 1.游戏陪练&#xff1a;可以选择当下火爆的游戏内容&#xff0c;选择游戏大神、职业玩家进行陪练&#xff0c;也可约附近路人玩家或是身边的小伙伴语音组队开黑&#xff0c;一起享受边玩游戏边吐槽的无限乐趣。 2.约玩交友&#xff1a;除了游戏陪玩功能&a…

通过安卓模拟器使直播软件obs的0粉丝用户开播

1.安装夜神安卓模拟器 实测这玩意效率比逍遥模拟器快很多&#xff0c;破逍遥跑抖音都卡 安装好后&#xff0c;和手机同一个抖音账号 2.打开弹幕助手&#xff0c;用抖音扫描二维码登录 3.模拟器里&#xff0c;抖音设置里&#xff0c;最下面版本纯文字字样&#xff0c;连续点击…

chatgpt引入思考过程还是会出错?为什么不让机器检讨检讨自己(李宏毅)

原始视频&#xff1a;李宏毅&#xff1a;ChatGPT可以自我反省 一、单个模型自我反省 二、两个模型彼此讨论 三、同时引入思考搜索 3.1 单独引入思考或者添加搜索结果还是可能出错 3.2 同时引入搜索思考过程&#xff08;给出几个例子就可能得到比较好的结果&#xff09; 思考的过…

[漏洞分析] CVE-2022-0847 Dirty Pipe linux内核提权分析

CVE-2022-0847 Dirty Pipe linux内核提权分析 文章目录 CVE-2022-0847 Dirty Pipe linux内核提权分析漏洞简介环境搭建漏洞原理漏洞发生点pipe原理与pipe_writesplice到copy_page_to_iter_pipelinux 内核page cache机制 漏洞利用细节调试exp一些小限制(无伤大雅) 缓解措施建议方…

通过HackerOne漏洞报告学习PostMessage漏洞实战场景中的利用与绕过

转载https://www.anquanke.com/post/id/219088 0x00 前言 这是一篇关于postMessage漏洞分析的文章&#xff0c;主要通过hackerone平台披露的Bug Bounty报告&#xff0c;学习和分析postMessage漏洞如何在真实的场景中得到利用的。 0x01 什么是PostMessage 根据Mozilla开发文档…

我的一些实战的漏洞挖掘过程(一)

最近挖到的漏洞&#xff0c;在这里分享一下&#xff0c;有些信息比较敏感就打码处理&#xff0c;目标网站都换为target.com 反射xss漏洞挖掘 跨站脚本攻击&#xff08;Cross-site Scripting&#xff0c;XSS&#xff09;是一种常见的Web安全漏洞&#xff0c;攻击者通过在Web应…

漏洞挖掘之信息收集

简介 对单一指定目标网站进行黑盒测试&#xff0c;最重要的就是信息收集&#xff0c;因为网站管理员肯定会在用户经常访问的主网站进行经常维护&#xff0c;而那些子域名&#xff0c;没有什么人访问的&#xff0c;可能就会忘记维护&#xff0c;挖洞的突破点大都在于子域名上&am…

我的HackerOne漏洞赏金平台漏洞挖掘流程

简介 高强度在hackerone平台挖了一周的漏洞&#xff0c;在这里分享一下经验 选定目标 hackerone有两种src&#xff0c;一种是给钱的&#xff0c;一种是免费的&#xff0c;我一般都是选的有钱的去挖 假如我选择了这个作为今天的挖洞目标 首先需要往下滑&#xff0c;看他不收…

麦肯锡教我的思考武器-读书心得

《麦肯锡教我的思考武器》从逻辑思考到真正解决问题&#xff0c;思考&#xff0c;不要使用蛮力&#xff0c;工作&#xff0c;不只靠体力&#xff01;从议题出发&#xff0c;创造有价值的工作。面对任务繁多的工作&#xff0c;你该如何应付&#xff1f;对于专业工作者而言&#…

麦肯锡三部曲_麦肯锡三部曲推荐

人生&#xff0c;唯有读书与运动不可辜负。 今日推荐&#xff1a; 艾森拉塞尔和保罗弗里嘉所著的麦肯锡三部曲&#xff1a;《麦肯锡方法》、《麦肯锡意识》和《麦肯锡工具》。 作者简介&#xff1a; 艾森拉塞尔(Ethan M. Rasiel)是麦肯锡纽约公司的一名顾问。他的客户包括在金融…

《麦肯锡意识》前言 解决问题的战略模型-思维导图

《麦肯锡意识》前言 解决问题的战略模型-思维导图 文章目录 解决问题的理论模型解决问题的战略模型客户需求分析汇报管理实施领导力 本书侧重探讨此模型的分析、汇报和管理部分 本书的基础是麦肯锡所实践的解决问题流程 关于解决问题流程 解决问题的理论模型 战略模型图&…

《麦肯锡方法》读书笔记22

《爱数圈-每日悦享读书会》打卡&#xff1a;第二十一章 关于麦肯锡的回忆&#xff1a;

《麦肯锡方法》第12章 管理公司的内部沟通-思维导图

文章目录 麦肯锡的内部沟通让信息流动起来蘑菇种植法保持信息的通畅内部沟通 有效信息的三个关键因素简洁全面系统 慎言慎行 麦肯锡的内部沟通 以团队为基础的运营&#xff0c;其成功与否有赖于沟通 自上而下的沟通自下而上的沟通 沟通方式 电子邮件备忘录会议… 让信息流动…

《麦肯锡方法》第1章建立解决方案-思维导图

《麦肯锡方法》第1章建立解决方案-思维导图 文章目录 第1章 建立解决方案 与事实为友 优先收集和分析事实 事实为何如此重要&#xff1f; 事实弥补了直觉的缺陷事实可提高可信度 对MECE原则应用自如 分解问题 把大的复杂的问题&#xff0c;拆分成小的容易解决的子问题子问题…

《麦肯锡方法》第13章 与客户合作-思维导图

《麦肯锡方法》第13章 与客户合作-思维导图 文章目录 与客户团队合作让客户团队站到你这边如何与客户团队中的”讨债鬼“打交道让客户参与工作获得整个公司的支持实施要严谨 与客户团队合作 最大限度地发挥客户团队的积极性 怎样让客户在项目中发挥积极影响并限制消极影响 对…

用讯飞星火大模型1分钟写一个精美的PPT

文章目录 前言SparkDesk讯飞星火认知大模型简介利用讯飞星火写一个转正述职ppt1.告诉讯飞星火我想写一篇转正述职ppt2.利用MindShow一键生成ppt 申请体验写在最后 ✍创作者&#xff1a;全栈弄潮儿 &#x1f3e1; 个人主页&#xff1a; 全栈弄潮儿的个人主页 &#x1f3d9;️ 个…

ChatGpt AI智能绘画java开源系统快速搭建

要快速搭建AI智能绘画的Java开源系统&#xff0c;您可以按照以下步骤进行操作&#xff1a; 确定系统需求&#xff1a;明确您希望系统具备哪些功能和特性&#xff0c;例如图像处理、机器学习、深度学习等方面。 寻找相关开源库和框架&#xff1a;Java生态系统中存在许多强大的开…