地图导航功能的实现 之 ROS通信

地图导航分为三个部分,第一个部分为雷达部分的ROS系统,第二部分为通信部分,一般有http协议,ros协议(ROSjava和Rosbridge协议),zmq协议等,第三部分为安卓端和用户交互部分。这里介绍一下通信部分。

一. RosJava协议

ROS官方支持的绑定只有C++和Python,所以目前安卓想与ROS通信,必须借助官方的ROSjava包,通过ROSjava实现与ROS端的通信并进行地图绘制。使用ROSjava开发,需要熟悉gradle脚本,对rosjava进行编译,当然也可以直接使用官方提供的demo,在相应的基础上进行开发。

RosAndroid初始化map地图显示:

 protected void init(NodeMainExecutor nodeMainExecutor) {

super.init(nodeMainExecutor);

        this.nodeMainExecutor = nodeMainExecutor;
        nodeConfiguration = NodeConfiguration.newPublic(InetAddressFactory
                .newNonLoopback().getHostAddress(), getMasterUri());
        String joyTopic = remaps.get(getString(R.string.joystick_topic));
        String camTopic = remaps.get(getString(R.string.camera_topic));

        NameResolver appNameSpace = getMasterNameSpace();
        joyTopic = appNameSpace.resolve(joyTopic).toString();
        camTopic = appNameSpace.resolve(camTopic).toString();
        cameraView.setTopicName(camTopic);
        virtualJoystickView.setTopicName(joyTopic);

        nodeMainExecutor.execute(cameraView,
                nodeConfiguration.setNodeName("android/camera_view"));
        nodeMainExecutor.execute(virtualJoystickView,
                nodeConfiguration.setNodeName("android/virtual_joystick"));
        ViewControlLayer viewControlLayer = new ViewControlLayer(this,
                nodeMainExecutor.getScheduledExecutorService(), cameraView,
                mapView, mainLayout, sideLayout, params);

        String mapTopic   = remaps.get(getString(R.string.map_topic));
        String scanTopic  = remaps.get(getString(R.string.scan_topic));
        String robotFrame = (String) params.get("robot_frame", getString(R.string.robot_frame));

        occupancyGridLayer = new OccupancyGridLayer(appNameSpace.resolve(mapTopic).toString());
        laserScanLayer = new LaserScanLayer(appNameSpace.resolve(scanTopic).toString());
        robotLayer = new RobotLayer(robotFrame);

        mapView.addLayer(viewControlLayer);
        mapView.addLayer(occupancyGridLayer);
        mapView.addLayer(laserScanLayer);
        mapView.addLayer(robotLayer);

        mapView.init(nodeMainExecutor);
        viewControlLayer.addListener(new CameraControlListener() {
            @Override
            public void onZoom(float focusX, float focusY, float factor) {
                Logger.v("focusX1: " + focusX + "focusY1:" + focusY + "factor1:" + factor);
            }
            @Override
            public void onDoubleTap(float x, float y) {
                Logger.v("x: " + x + "y:" + y );
            }
            @Override
            public void onTranslate(float distanceX, float distanceY) {
                Logger.v("distanceX: " + distanceX + "distanceY:" + distanceY );
            }
            @Override
            public void onRotate(float focusX, float focusY, double deltaAngle) {
                Logger.v("focusX2: " + focusX + "focusY2:" + focusY + "factor2:" + deltaAngle);
            }
        });
        nodeMainExecutor.execute(mapView, nodeConfiguration.setNodeName("android/map_view"));

    }

保存地图:

try {
            final MapManager mapManager = new MapManager(MakeMapActivity.this, remaps);
            if (name != null) {
                mapManager.setMapName(name);
            }
            mapManager.setNameResolver(getMasterNameSpace());
            mapManager.registerCallback(new MapManager.StatusCallback() {
                @Override
                public void timeoutCallback() {
                    safeDismissWaitingDialog();
                    safeShowNotiDialog("Error", "Timeout");
                }
                @Override
                public void onSuccessCallback(SaveMapResponse arg0) {
                    safeDismissWaitingDialog();
                    safeShowNotiDialog("Success", "Map saving success!");
                }
                @Override
                public void onFailureCallback(Exception e) {
                    safeDismissWaitingDialog();
                    safeShowNotiDialog("Error", e.getMessage());
                }
            });

            nodeMainExecutor.execute(mapManager,
                    nodeConfiguration.setNodeName("android/save_map"));

        } catch (Exception e) {
            e.printStackTrace();
            safeShowNotiDialog("Error", "Error during saving: " + e.toString());
        }


二.rosbridge协议

对websocket的一直封装协议。rosbridge相对于rosjava更方便与简洁,可以自定义地图数据节点json协议。

通过:广播,话题,订阅,发布来与ros系统进行通信。

通过WebSocketClient连接ros服务端:

  boolean conneSucc = client.connect(new ROSClient.ConnectionStatusListener() {
            @Override
            public void onConnect() {
                client.setDebug(true);
                ((RCApplication)getApplication()).setRosClient(client);
                showTip("Connect ROS success");
                Log.d(TAG,"Connect ROS success");
                startActivity(new Intent(MainActivity.this,NodesActivity.class));
            }

            @Override
            public void onDisconnect(boolean normal, String reason, int code) {
                showTip("ROS disconnect");
                Log.d(TAG,"ROS disconnect");
            }

            @Override
            public void onError(Exception ex) {
                ex.printStackTrace();
                showTip("ROS communication error");
                Log.d(TAG,"ROS communication error");
            }
        });
 public boolean connect(ROSClient.ConnectionStatusListener listener) {
        boolean result = false;
        client = ROSBridgeWebSocketClient.create(uriString);
        if (client != null) {
            client.setListener(listener);
            try {
                result = client.connectBlocking();
            }
            catch (InterruptedException ex) {}
        }
        return result;
    }
public static ROSBridgeWebSocketClient create(String URIString) {
        ROSBridgeWebSocketClient client = null;
        try {
            URI uri = new URI(URIString);
            client = new ROSBridgeWebSocketClient(uri);
        }
        catch (URISyntaxException ex) {
            ex.printStackTrace();
        }
        return client;
    }

通信广播/话题/订阅/发布消息:

@MessageType(string = "rosapi/Services")
public class Services extends Message {
    public String[] services;
}

@MessageType(string = "rosapi/Topic")
public class Topic extends Message {
    public String topic;
    
    public Topic() {}
    
    public Topic(String topic) {
        this.topic = topic;
    }
}

public class PublishEvent {
    public String msg;
    public String id;
    public String name;
    public String op;


    public PublishEvent(Operation operation,String name, String content) {
        if(operation != null) {
            id = operation.id;
            op = operation.op;
        }
        this.name = name;
        msg = content;
    }
}
@MessageType(string = "call_service")
public class CallService extends Operation {
    @Indicator public String service;
    @Indicated @AsArray public Message args;  
    public Integer fragment_size; // use Integer for optional items
    public String compression;

    public CallService() {}
    
    public CallService(String service, Message args) {
        this.service = service;
        this.args = args;
    }    
}

通过获取/发送的json进行通信:

{\"op\":\"call_service\",\"service\":\"/add_two_ints\",\"args\":{\"a\":2,\"b\":8}}
{\"op\":\"call_service\",\"service\":\"scanmap\",\"args\":{\"type\":\"save\"},\"info\":{\"mapName\":\"tianyicesuo\",\"type\":8}}");//"{\"op\":\"call_service\",\"service\":\"scanmap\",\"args\":{\"a\":\"start\"}}
{\"op\":\"call_service\",\"service\":\"scanmap\",\"args\":{\"type\":\"save\"},\"info\":{\"mapName\":\"tianyicesuo\",\"type\":8}}


RosAndroid DEMO 

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
ROS(Robot Operating System)是一个开源的机器人操作系统,提供了一系列的工具、库和软件以帮助开发者构建机器人应用。在ROS中,可以通过使用SLAM(Simultaneous Localization and Mapping)算法来自定义地图。 首先,在ROS中使用机器人进行地图开发,需要将机器人与ROS系统进行连接。可以使用ROS提供的通信库来与机器人进行通信,将机器人的传感器数据和控制命令通过ROS系统进行传输。 其次,在ROS中使用SLAM算法进行地图的自定义开发。SLAM算法可以同时进行机器人的定位和地图的建立。通过机器人的传感器数据(如激光雷达、摄像头等)和运动控制信息,可以利用SLAM算法实时地构建机器人所在环境的地图ROS提供了多种SLAM算法的实现,例如gmapping、Cartographer等。可以根据具体需求选择合适的算法。 在地图开发过程中,还可以选择使用ROS提供的可视化工具来实时显示地图的建立过程。ROS提供了rviz工具,可以将机器人的传感器数据和地图信息进行可视化展示,方便开发者进行实时监控和调试。 最后,地图开发完成后,可以将地图保存为ROS支持的文件格式,如Occupancy Grid Map或点云数据等。这样,在后续的机器人导航和路径规划等应用中,可以直接使用自定义的地图进行定位和导航。 总结来说,ROS提供了丰富的工具和算法,方便开发者进行自定义地图的开发。通过连接机器人、使用SLAM算法、可视化展示和地图保存等步骤,可以实现高质量的地图开发。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值