欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 金融 > 做一个能和你互动玩耍的智能机器人之五-app代码设计

做一个能和你互动玩耍的智能机器人之五-app代码设计

2024/10/24 11:19:05 来源:https://blog.csdn.net/blogercn/article/details/140744226  浏览:    关键词:做一个能和你互动玩耍的智能机器人之五-app代码设计

openbot使用手机做大脑,这使得我们可以做很多的AI算法来实现诸如循迹,避障,跟随,寻光,人体感应等传感器,使得整个项目的设计更简单和更经济,减少的很多的传感器都会降低硬件DIY的难度和花费。缺点是需要学习一下caffee或tensorFolw Lite,根据我的感觉,也可以使用这些芯片减少来开发的难度,国内网店上这些芯片价格并不高,几块钱就能搞定,如果没有手机,使用传感器是个很好的选择。连无线充电模块都能买到,那些不使用手机的机器人应该是使用了这些芯片。

openbot的android代码位于根目录的android目录下,包含两个模块,一个控制,一个机器人app。

IOS目录是IOS 的app

doc目录是说明文档。

opencode很有意思,是一个在线开发固件的平台,通过拖放就可以,这可以节省很多写代码的时间。

policy是一个驾驶策略训练的平台,需要有比较强劲的电脑和tensorflow知识,主要是采集吧

python手机控制训练。

不要害怕动手。自己买很便宜,购买时自己可以购买一些杜邦线和arduino的扩展板,我也是后来才知道,arduino uno有Arduino sensor shield V5.0的扩展板,arduino有cnc shield v4的扩展板,结合杜邦线,都是几块钱,就能让接入更加轻松,这样调试会更方便,而且省掉很多焊接。

android代码需要的android studio版本比较新,老版需要自己适配gradle,安装好以后就可以插上arduino测试。

然后就可以自己自己开发加一些表情集,为了提高复用性,我倾向于不使用控件而是基本的绘图api来实现,这可以使之十分方便的移植到其他语言和平台。

一个简单的自定义VIEW:

public class FaceView extends View{private static final String TAG = "FaceView";private Paint mPaint;private RectF oval;//是否圆眼private boolean m_bCircle=true ;//是否显示嘴private boolean isShowMouth=false;//表情索引private int mFace=0;//view Widthprivate int m_VW = 0;//view heightprivate int m_VH = 0;//X轴中心private float mRadiusX = 0;//Y轴中心private float mRadiusY = 0;//圆角半径private float m_rx = 0;private float m_ry = 0;//左眼矩形位置private float m_left_Leye = 0;private float m_left_Teye = 0;private float m_left_Reye = 0;private float m_left_Beye = 0;//左眼中心private float m_left_Xeye = 0;private float m_left_Yeye = 0;//圆眼的半径private float m_eye_R = 0;//右眼位置private float m_right_Leye = 0;private float m_right_Teye = 0;private float m_right_Reye = 0;private float m_right_Beye = 0;//右眼中心private float m_right_Xeye = 0;private float m_right_Yeye = 0;private RectF m_l_oval;private RectF m_r_oval;//表情添加过渡动画private ValueAnimator va;private float mCurrentSingle = 0f;private boolean isRun = false;

view初始化,为了调试方便,我在view加入了一个单击切换表情的操作。

 private void initView() {mPaint= new Paint();mPaint.setAntiAlias(true);oval = new RectF();mPaint.setColor(Color.YELLOW);mPaint.setStyle(Paint.Style.FILL_AND_STROKE);this.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {mFace++;if (mFace > 20){mFace = 0;}isRun = false;invalidate();}});m_l_oval = new RectF();m_r_oval = new RectF();initAni();}
private void initAni() {Log.i("jiaXXX", "enter drawAni");if (va == null) {Log.i("jiaXXX", "enter drawAni========");va = ObjectAnimator.ofFloat(0f, 1);va.setDuration(300);//va.setRepeatCount(ValueAnimator.INFINITE);//va.setRepeatCount(0);va.setInterpolator(new AccelerateInterpolator());//va.start();va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {mCurrentSingle = (float) animation.getAnimatedValue();invalidate();Log.i("jiaXXX", "enter drawAni========, onAnimationUpdate");}});va.addListener(new Animator.AnimatorListener() {@Overridepublic void onAnimationStart(Animator animation) {}@Overridepublic void onAnimationEnd(Animator animation) {Log.i("jiaXXX", "enter drawAni========, onAnimationEnd");if (va != null) {Log.i("jiaXXX", "enter drawAni========, onAnimationEnd----");//va.end();va.cancel();//va = null;//isRun = false;}}@Overridepublic void onAnimationCancel(Animator animation) {Log.i("jiaXXX", "enter drawAni======== onAnimationCancel");if (va != null) {Log.i("jiaXXX", "enter drawAni======== onAnimationCancel----");//va = null;//isRun = false;}}@Overridepublic void onAnimationRepeat(Animator animation) {}});}}

显示表情:

 protected void onDraw(Canvas canvas) {super.onDraw(canvas);canvas.drawColor(Color.BLACK);m_VW = getWidth();m_VH = getHeight();Log.i("jia", "w="+m_VW);Log.i("jia", "h="+m_VH);//view 中心mRadiusX = m_VW / 2;mRadiusY = m_VH / 2;//眼睛半径if ( m_VW > m_VH){m_eye_R = m_VH / 4;}else {m_eye_R = m_VW / 5;}//左眼中心if ( m_VW > m_VH){m_left_Xeye = mRadiusX-m_eye_R-(m_eye_R/3);}else {m_left_Xeye = m_VW / 4;}//右眼中心m_left_Yeye = m_VH / 2;if ( m_VW > m_VH) {m_right_Xeye = mRadiusX+m_eye_R+(m_eye_R/3);}else {m_right_Xeye = m_VW * 3 / 4;}m_right_Yeye = m_VH / 2;//默认方眼的四个顶点位置,为了好看,方眼y方向做一放缩m_left_Leye = m_left_Xeye - m_eye_R;m_left_Teye = m_left_Yeye - m_eye_R*1.2f;m_left_Reye = m_left_Xeye + m_eye_R;m_left_Beye = m_left_Yeye + m_eye_R*1.2f;//当眼睛为方的时,圆角半径m_rx = m_eye_R/10;m_ry = m_eye_R/10;m_right_Leye = m_right_Xeye - m_eye_R;m_right_Teye = m_right_Yeye - m_eye_R*1.2f;m_right_Reye = m_right_Xeye + m_eye_R;m_right_Beye = m_right_Yeye + m_eye_R*1.2f;//m_left_Xeye = m_left_Xeye+(float) Math.sin(mCurrentSingle * 50) * 8;//m_left_Yeye = m_left_Xeye+(float) Math.sin(mCurrentSingle * 50) * 8;if (mFace == 0) {drawFace(canvas);}else if (mFace == 1) {drawFace1(canvas);}else if (mFace == 2) {drawFace2(canvas);}else if (mFace == 3) {drawFace3(canvas);}else if (mFace == 4) {drawFace4(canvas);}else if (mFace == 5) {drawFace5(canvas);}else if (mFace == 6) {drawFace6(canvas);}else if (mFace == 7) {drawFace7(canvas);}else if (mFace == 8) {drawFace8(canvas);}else if (mFace == 9) {drawFace9(canvas);}else if (mFace == 10) {drawFace10(canvas);}else if (mFace == 11) {drawFace11(canvas);}else if (mFace == 12) {drawFace12(canvas);}else if (mFace == 13) {drawFace13(canvas);}else if (mFace == 14) {drawFace14(canvas);}else if (mFace == 15) {drawFace15(canvas);}else if (mFace == 16) {drawFace16(canvas);}else{drawFace(canvas);}//invalidate();//drawAni(canvas);}

初始化的眼睛从小到大一个睁眼的动作

private void drawFace(Canvas canvas){mPaint.setColor(Color.WHITE);if (m_bCircle){//canvas.drawCircle(m_left_Xeye, m_left_Yeye, m_eye_R, mPaint);//canvas.drawCircle(m_right_Xeye, m_right_Yeye, m_eye_R, mPaint);m_l_oval.set(m_left_Leye, m_left_Yeye-m_eye_R*mCurrentSingle, m_left_Reye, m_left_Yeye+m_eye_R*mCurrentSingle);//绘制圆弧  圆弧所在的椭圆对象 圆弧的起始角度 圆弧的角度 是否显示半径连线canvas.drawArc(m_l_oval, 0, 360, true, mPaint);m_r_oval.set(m_right_Leye, m_right_Yeye-m_eye_R*mCurrentSingle, m_right_Reye, m_right_Yeye+m_eye_R*mCurrentSingle);//绘制圆弧  圆弧所在的椭圆对象 圆弧的起始角度 圆弧的角度 是否显示半径连线canvas.drawArc(m_r_oval, 0, 360, true, mPaint);if (!isRun) {Log.i("jiaXXX", "drawAni");isRun = true;//drawAni(canvas);va.start();}}else{canvas.drawRoundRect(m_left_Leye, m_left_Teye, m_left_Reye, m_left_Beye, m_rx, m_ry, mPaint);canvas.drawRoundRect(m_right_Leye, m_right_Teye, m_right_Reye, m_right_Beye, m_rx, m_ry, mPaint);}}
  //闭眼,叹气private void drawFace1(Canvas canvas){mPaint.setColor(Color.WHITE);if (m_bCircle){m_l_oval.set(m_left_Leye, m_left_Teye+m_eye_R*mCurrentSingle, m_left_Reye, m_left_Beye-m_eye_R*mCurrentSingle);//绘制圆弧  圆弧所在的椭圆对象 圆弧的起始角度 圆弧的角度 是否显示半径连线canvas.drawArc(m_l_oval, 0, 360, false, mPaint);m_r_oval.set(m_right_Leye, m_right_Teye+m_eye_R*mCurrentSingle, m_right_Reye, m_right_Beye-m_eye_R*mCurrentSingle);//绘制圆弧  圆弧所在的椭圆对象 圆弧的起始角度 圆弧的角度 是否显示半径连线canvas.drawArc(m_r_oval, 0, 360, false, mPaint);if (!isRun) {Log.i("jiaXXX", "drawAni");isRun = true;//drawAni(canvas);va.start();}}else{canvas.drawRoundRect(m_left_Leye, m_left_Teye+m_eye_R, m_left_Reye, m_left_Beye-m_eye_R, m_rx, m_ry, mPaint);canvas.drawRoundRect(m_right_Leye, m_right_Teye+m_eye_R, m_right_Reye, m_right_Beye-m_eye_R, m_rx, m_ry, mPaint);}}//下半睁private void drawFace2(Canvas canvas){mPaint.setColor(Color.WHITE);if (m_bCircle){m_l_oval.set(m_left_Leye, m_left_Yeye-m_eye_R, m_left_Reye, m_left_Yeye+m_eye_R);//绘制圆弧  圆弧所在的椭圆对象 圆弧的起始角度 圆弧的角度 是否显示半径连线canvas.drawArc(m_l_oval, 0, 180, true, mPaint);RectF r1= new RectF();r1.set(m_left_Leye, m_left_Yeye-(m_eye_R/5)-(m_eye_R*4/5)*(1-mCurrentSingle), m_left_Reye, m_left_Yeye+(m_eye_R/5)+(m_eye_R*4/5)*(1-mCurrentSingle));//绘制圆弧  圆弧所在的椭圆对象 圆弧的起始角度 圆弧的角度 是否显示半径连线Paint p = new Paint();p.setColor(Color.BLACK);canvas.drawArc(r1, 0, -180, true, mPaint);m_r_oval.set(m_right_Leye, m_right_Yeye-m_eye_R, m_right_Reye, m_right_Yeye+m_eye_R);//绘制圆弧  圆弧所在的椭圆对象 圆弧的起始角度 圆弧的角度 是否显示半径连线canvas.drawArc(m_r_oval, 0, 180, true, mPaint);RectF r2= new RectF();r2.set(m_right_Leye, m_right_Yeye-(m_eye_R/5)-(m_eye_R*4/5)*(1-mCurrentSingle), m_right_Reye, m_right_Yeye+(m_eye_R/5)+(m_eye_R*4/5)*(1-mCurrentSingle));//绘制圆弧  圆弧所在的椭圆对象 圆弧的起始角度 圆弧的角度 是否显示半径连线canvas.drawArc(r2, 0, -180, true, mPaint);if (!isRun) {Log.i("jiaXXX", "drawAni");isRun = true;va.start();}}else{canvas.drawRoundRect(m_left_Leye, m_left_Teye+m_eye_R, m_left_Reye, m_left_Beye, m_rx, m_ry, mPaint);canvas.drawRoundRect(m_right_Leye, m_right_Teye+m_eye_R, m_right_Reye, m_right_Beye, m_rx, m_ry, mPaint);}}//上半睁private void drawFace3(Canvas canvas){mPaint.setColor(Color.WHITE);if (m_bCircle){canvas.drawCircle(m_left_Xeye, m_left_Yeye, m_eye_R, mPaint);canvas.drawCircle(m_right_Xeye, m_right_Yeye, m_eye_R, mPaint);Paint p = new Paint();p.setColor(Color.BLACK);canvas.drawRect(m_left_Leye, mRadiusY+m_eye_R/3+(m_eye_R*2/3)*(1-mCurrentSingle), m_right_Reye, m_right_Beye, p);if (!isRun) {Log.i("jiaXXX", "drawAni");isRun = true;va.start();}}else{canvas.drawRoundRect(m_left_Leye, m_left_Teye, m_left_Reye, m_left_Beye-m_eye_R, m_rx, m_ry, mPaint);canvas.drawRoundRect(m_right_Leye, m_right_Teye, m_right_Reye, m_right_Beye-m_eye_R, m_rx, m_ry, mPaint);}}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com