...
- 控制底盘行走
遥控控制底盘行走
遥控底盘需要使用moveBy接口,接口中传入动作类型指令,其代码主要位于每个按键的触摸响应函数中,以“向前”按键为例Code Block language java theme RDarkDJango linenumbers true // go forward int delayTime = 300; button_forward.setLongClickRepeatListener(new LongClickButton.LongClickRepeatListener() { @Override public void repeatAction() { try { moveAction = robotPlatform.moveBy(MoveDirection.FORWARD); System.out.println("repeatAction==============="); } catch (Exception e) { e.printStackTrace(); } } }, delayTime);
自主规划路径行走
Code Block theme DJango linenumbers true button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if(targetX.length()==0 || targetY.length()==0) { Toast.makeText(MainActivity.this, "请输入目标点坐标", Toast.LENGTH_SHORT).show(); } else { try { float x = Float.parseFloat(targetX.getText().toString()); float y = Float.parseFloat(targetY.getText().toString()); MoveOption moveOption = new MoveOption(); moveOption.setPrecise(true); moveOption.setMilestone(true); Log.d(TAG, "Move To"); moveAction = robotPlatform.moveTo(new Location(x, y, 0), moveOption, 0); // action.waitUntilDone(); } catch (Exception e) { e.printStackTrace(); } } } });
自主规划路径使用moveTo接口,接口中传入目标位置坐标点,其代码位于“到这里”按键的点击监控函数中
实时更新底盘状态和地图
实时更新是Android Runable多线程类实现的,Runable对象中的update方法 每100毫秒执行一次
Code Block theme DJango linenumbers true private Handler handler = new Handler(); private Runnable runnable = new Runnable() { public void run() { this.update(); handler.postDelayed(this, 100);// 间隔100ms } ... }
以下是update中的刷新底盘Pose和剩余电量的代码。
Code Block theme DJango firstline 1 linenumbers true void update() { try { /* 刷新Pose */ Pose pose = robotPlatform.getPose(); current_location_x.setText(Float.toString(pose.getX())); current_location_y.setText(Float.toString(pose.getY())); current_location_yaw.setText(Float.toString(pose.getYaw())); /* 刷新电量 */ int percentage = robotPlatform.getBatteryPercentage(); current_battery_percentage.setText(Integer.toString(percentage)); ... } catch(Exception e) { ... } }
地图绘制是通过BitmapDrawable方法完成的,其使用getMa接口,从Slamcode获得实时的地图数据,该数据是像素点的原始数据(raw data),不存在任何图片格式信息,为了显示在界面上,将其封装成Bitmap ARGB_8888图像,之后显示在图形界面上。
Code Block theme DJango linenumbers true /* 获取地图并刷新 */ int mapWidth =0; int mapHeight = 0; RectF knownArea = robotPlatform.getKnownArea(MapType.BITMAP_8BIT, MapKind.EXPLORE_MAP); map = robotPlatform.getMap(MapType.BITMAP_8BIT, MapKind.EXPLORE_MAP, knownArea); mapWidth = map.getDimension().getWidth(); mapHeight = map.getDimension().getHeight(); Bitmap bitmap = Bitmap.createBitmap(mapWidth, mapHeight, ARGB_8888); for (int posY = 0; posY < mapHeight; ++posY) { for (int posX = 0; posX < mapWidth; ++posX) { // get map pixel byte[] data = map.getData(); // (-128, 127) to (0, 255) int rawColor = data[posX + posY * mapWidth]; rawColor += 128; // fill the bitmap data, by data of B/G/R/A bitmap.setPixel(posX, posY, rawColor | rawColor<<8 | rawColor<<16 | 0xC0<<24); } } BitmapDrawable bmpDraw=new BitmapDrawable(bitmap); imageView.setImageDrawable(bmpDraw);
上面的代码仅用于演示如何操作地图数据并将其显示。
上述代码可能存在性能较低的问题,包括但不限于每次均重画所有像素数据,如果地图面积很大,会导致刷新速度较慢;每100毫秒重画一次地图,如果BitmapDrawable自身所需时间大于100ms,会造成严重的显示问题,等等。
建议在实际编写应用程序时,需认真考虑地图绘制的时效性以及稳定性。
...