Skip to content

JoMission使用教程(Java面向对象接口)

简介

JoCPL通过SWIG导出为Java的接口,并进行了面向对象的封装。通过使用该Java的SDK,可以方便的进行航线规划、高程下载等操作。有关Java的API使用教程如下。

教程

1 航线规划

1.1 创建载荷

载荷是挂载在无人机上的工作设备,包括吊舱、相机、激光雷达等。JoCPL通过Sensor类进行表示,下面以创建一个相机为例体现如何创建一个载荷:

java
import com.jo.cpl.scripts.Sensor; // 导入载荷类

Sensor sensor = new Sensor(); // 创建新的载荷

sensor.setFOV(90.0); // 设置视场角
sensor.setFocalLength(0.5); // 设置焦距,焦距和视场角是可以互相转换的参数
sensor.setModel("CA102/35mm"); // 设置载荷类型
sensor.setPixelXSize(7952); // 设置载荷像素尺寸的长度
sensor.setPixelYSize(5304); // 设置载荷像素尺寸的宽度
sensor.setFrameXSize(34.9999328); // 设置载荷像素尺寸的长度
sensor.setFrameYSize(23.3450256); // 设置载荷像素尺寸的宽度
sensor.setFrameZSize(21.0); // 设置载荷与载体X方向的偏移量
sensor.setFrameXOffset(0.0); // 设置载荷与载体Y方向的偏移量
sensor.setFrameYOffset(0.0); // 设置载荷与载体Z方向的偏移量
sensor.setFrameZOffset(0.0); // 设置载荷像素尺寸的深度
sensor.setFrameXRotation(0.0); // 设置载荷与载体X轴方向的角度偏移量
sensor.setFrameYRotation(0.0); // 设置载荷与载体Y轴方向的角度偏移量
sensor.setFrameZRotation(0.0); // 设置载荷与载体Z轴方向的角度偏移量

1.2 创建载体

载体是指挂载载荷进行工作的行动体,不仅是无人机,还包括无人船、无人车以及机器人等。JoCPL通过Vehicle类进行表示,下面以创建一个搭载相机的垂直起降固定翼无人机为例体现如何创建一个载体:

java
import com.jo.cpl.scripts.Vehicle;  // 导入载体类

double orbitRadius = 120.0; // 转弯半径
double floor = 100.0; // 最低飞行高度
double ceiling = 3000.0; // 最高飞行高度
double clearance = 300.0; // 相对基准面的标准净空距离
double descendLimit = 15.0; // 极限下滑角
double ascendLimit = 15.0; // 极限爬升角

Vehicle vehicle = new Vehicle(orbitRadius, floor, ceiling, clearance, descendLimit, ascendLimit); // 创建新的载体
vehicle.setModel("CW-15II"); // 设置载体类型

vehicle.setPayload(sensor); // 载体挂载上面创建的载荷

1.3 创建人员

人员是载体的操作者,或者是整个工作任务的指挥者,不同的人员类别,对应着不用的权限。在JoCPL中,使用Player表示人员,下面以创建一个指挥官和一个执行者为例,形成指挥官指挥执行者,执行者控制载体,载体搭载载荷的链条:

java
import com.jo.cpl.scripts.Player;  // 导入人员类
import com.jo.cpl.scripts.Entity;
import com.jo.cpl.scripts.Coordinate;

Player commander = new Player(); // 创建指挥者
Player performer = new Player(); // 创建执行者
performer.setMecha(vehicle); // 为执行者设置上面创建的载体
performer.setLeader(commander); // 设置执行者的指挥官为指挥者

Coordinate pos = new Coordinate(); // 创建一个坐标点并设置属性
pos.setX(104.483343433216);
pos.setY(31.6131756839056);
pos.setZ(241.715682515960);
Entity home = new Entity(); // 创建一个home点
home.setPosition(pos); // 设置home点的位置
performer.setHome(home); // 为执行者设置home点

1.4 创建目标

目标分为点状目标,线状目标以及面状目标,同时对于不同的载体载荷目标也有不同的参数。JoCPL中使用Target表示一个目标,下面以线状目标为例,表现如何创建一个目标:

java
import com.jo.cpl.scripts.Target; // 导入目标类
import com.jo.cpl.scripts.GeometryType;
import com.jo.cpl.scripts.doubleVector;

double[ ] xs = {104.4366350, 104.4412414, 104.4506292, 104.4641861, 104.4636904, 104.4574514};
double[ ] ys = {31.5737925, 31.5818100, 31.5850170, 31.5840549, 31.5755418, 31.5717517};
double[ ] zs = {569.193480575, 554.826541635, 525.984043483, 600.018352627, 600.010287627, 600.010287627};
double[ ] ms = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
doubleVector dxs = new doubleVector(xs);
doubleVector dys = new doubleVector(ys);
doubleVector dzs = new doubleVector(zs);
doubleVector dms = new doubleVector(ms);
Target target = new Target(GeometryType.WKT_LineString, dxs, dys, dzs, dms); // 创建线状目标

target.setDatumElevation(400.0);
target.setIsTurningRight(true); // 设置目标的主转向符
target.setRouteSpacing(100.0); // 设置目标的航线间距
target.setFrontalBearing(90.0); // 设置目标的主航向角
target.setRelativeHeight(630.0); // 设置目标的相对航高
target.setFrontalEntryOffset(100.0); // 设置目标的航向进入偏移量
target.setFrontalLeaveOffset(100.0); // 设置目标的航向离开偏移量
target.setLateralEntryOffset(50.0); // 设置目标的旁向进入偏移量
target.setLateralLeaveOffset(50.0); // 设置目标的旁向离开偏移量
target.setDistanceToBuffer(100.0); // 设置目标的缓冲区距离
target.setDescendMax(15.0); // 设置最大下滑角
target.setAscendMax(15.0); // 设置最大爬升角
target.setStripeCount(2); // 设置航线条数
target.findDatumElevation(); // 自动查询基准面高程

1.5 创建工程、工单和计划

JoCPL按照工程(Project)到工单(Order)到计划(Plan)的结构组织一个任务。一个工程可以包含多个工单,一个工单又可以包含多个计划,针对每一个计划,都可以进行航线的规划。下面将依赖上面的人员设备以及目标,创建可以执行的计划:

java
import com.jo.cpl.scripts.Project; // 导入工程类
import com.jo.cpl.scripts.Order; // 导入工单类
import com.jo.cpl.scripts.Plan; // 导入计划类
import com.jo.cpl.scripts.Entity;

Coordinate oriPos = new Coordinate(); // 设置起点
oriPos.setX(104.483343433216);
oriPos.setY(31.6131756839056);
oriPos.setZ(0.0);
Entity origination = new Entity();
origination.setPosition(oriPos);
Coordinate dstPos = new Coordinate();  // 设置终点
dstPos.setX(104.483343433216);
dstPos.setY(31.6131756839056);
dstPos.setZ(0.0);
Entity destination = new Entity();
destination.setPosition(dstPos);

Project project = new Project("project_1", commander, performer, origination, destination, "first project"); // 创建一个工程
Order order = project.createOrder("order_1", performer, origination, destination, "first order");  // 从工程创建一个工单
Plan plan = order.createPlan("plan_1", performer, origination, destination, "first plan"); // 从工单创建一个计划

1.6 规划航线并保存工程

上面已经完成了所有需要的对象的创建和设置,下面以监控航线规划器为例,展示在JoCPL中如何进行航线规划,并导出为GPKG格式的工程文件:

java
import com.jo.cpl.scripts.Planner; // 导入规划器类

Planner planner = new Planner(); // 创建新的规划器
planner.setDriver("Monitoring"); // 将规划器驱动设置为监控任务规划器
planner.replan(plan, target, true); // 规划航线,该目标为最后一个目标

project.saveAs("X:\XX\XX\XX.gpkg", "GPKG"); // 规划完成后保存工程文件

1.7 结果

完整代码如下:

java
import com.jo.cpl.scripts.Sensor;
import com.jo.cpl.scripts.Vehicle;
import com.jo.cpl.scripts.Player;
import com.jo.cpl.scripts.Entity;
import com.jo.cpl.scripts.Coordinate;
import com.jo.cpl.scripts.Target;
import com.jo.cpl.scripts.Geometry;
import com.jo.cpl.scripts.GeometryType;
import com.jo.cpl.scripts.DoubleVector;
import com.jo.cpl.scripts.Project;
import com.jo.cpl.scripts.Order;
import com.jo.cpl.scripts.Plan;
import com.jo.cpl.scripts.Planner;

class RibbonMonitoring {
    public static void main(String[] args) {
        Sensor sensor = new Sensor();
        sensor.setFOV(90.0);
        sensor.setFocalLength(0.5);
        sensor.setModel("CA103");
        sensor.setPixelXSize(7952);
        sensor.setPixelYSize(5304);
        sensor.setFrameXSize(34.9999328);
        sensor.setFrameYSize(23.3450256);
        sensor.setFrameZSize(21.0);
        sensor.setFrameXOffset(0.0);
        sensor.setFrameYOffset(0.0);
        sensor.setFrameZOffset(0.0);
        sensor.setFrameXRotation(0.0);
        sensor.setFrameYRotation(0.0);
        sensor.setFrameZRotation(0.0);
        assertThat(sensorOK).isTrue();

        double orbitRadius = 120.0;
        double floor = 100.0;
        double ceiling = 3000.0;
        double clearance = 300.0;
        double descendLimit = 15.0;
        double ascendLimit = 15.0;
        Vehicle vehicle = new Vehicle(orbitRadius, floor, ceiling, clearance, descendLimit, ascendLimit);
           vehicle.setModel("CW-15II");
        vehicle.setPayload(sensor);
        assertThat(vehicleOK).isTrue();

        Player commander = new Player();
        Player performer = new Player();
        performer.setMecha(vehicle);
        performer.setLeader(commander);
        Coordinate pos = new Coordinate();
        pos.setX(104.483343433216);
        pos.setY(31.6131756839056);
        pos.setZ(241.715682515960);
        Entity home = new Entity();
        home.setPosition(pos);
        performer.setHome(home);

        double[ ] xs = {104.4366350, 104.4412414, 104.4506292, 104.4641861, 104.4636904, 104.4574514};
        double[ ] ys = {31.5737925, 31.5818100, 31.5850170, 31.5840549, 31.5755418, 31.5717517};
        double[ ] zs = {569.193480575, 554.826541635, 525.984043483, 600.018352627, 600.010287627, 600.010287627};
        double[ ] ms = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
        DoubleVector dxs = new DoubleVector(xs);
        DoubleVector dys = new DoubleVector(ys);
        DoubleVector dzs = new DoubleVector(zs);
        DoubleVector dms = new DoubleVector(ms);
        Target target = new Target(GeometryType.WKT_LineString, dxs, dys, dzs, dms);
        target.setDatumElevation(400.0);
        target.setIsTurningRight(true);
        target.setRouteSpacing(100.0);
        target.setFrontalBearing(90.0);
        target.setRelativeHeight(630.0);
        target.setFrontalEntryOffset(100.0);
        target.setFrontalLeaveOffset(100.0);
        target.setLateralEntryOffset(50.0);
        target.setLateralLeaveOffset(50.0);
        target.setDistanceToBuffer(100.0);
        target.setDescendMax(15.0);
        target.setAscendMax(15.0);
        target.setStripeCount(2);
        target.findDatumElevation();

        Coordinate oriPos = new Coordinate();
        oriPos.setX(104.483343433216);
        oriPos.setY(31.6131756839056);
        oriPos.setZ(0.0);
        Entity origination = new Entity();
        origination.setPosition(oriPos);
        Coordinate dstPos = new Coordinate();
        dstPos.setX(104.483343433216);
        dstPos.setY(31.6131756839056);
        dstPos.setZ(0.0);
        Entity destination = new Entity();
        destination.setPosition(dstPos);
        Project project = new Project("project_1", commander, performer, origination, destination, "first project");
        Order order = project.createOrder("order_1", performer, origination, destination, "first order");
        Plan plan = order.createPlan("plan_1", performer, origination, destination, "first plan");

        Planner planner = new Planner();
        planner.setDriver("Monitoring");
        planner.replan(plan, target, true);

        project.saveAs("X:\XX\XX\XX.gpkg", "GPKG");
    }
}

保存后的工程文件使用GIS软件打开后可以看到,结果如下:

2 离线高程下载

2.1 指定范围高程下载

JoCPL的DEMManager提供有高程查询、栅格化航线等功能,可以通过在线的WCS数据或者本地的VRT数据进行高程的获取。因此提供了将在线高程数据下载到本地并组织为VRT的功能,使用JoCPL下载某区域的高程数据可以参考下列例子:

java
import com.jo.cpl.scripts.Envelope;
import com.jo.cpl.scripts.TermProgressCallback; // 导入回调函数类,可以继承这个类重写
import com.jo.cpl.scripts.DEMManager; // 导入高程管理类

Envelope extent = new Envelope(); // 创建和设置下载范围
extent.setMinX(86.3059);
extent.setMaxX(87.7510);
extent.setMinY(49.1722);
extent.setMaxY(49.7831);

TermProgressCallback downCallback = new TermProgressCallback(); // 创建回调函数
TermProgressCallback flashCallback = new TermProgressCallback();

DEMManager.setDataDir("X:\XX\XX\XX"); // 设置下载路径
DEMManager.setServiceUrl("www.xxx.com/wcs?SERVICE=WCS&COVERAGE=SRTM_GL1_CN:srtm"); // 设置访问的WCS的URL
DEMManager.requestTiles(extent, downCallback); // 下载数据
DEMManager.refreshTiles(flashCallback); // 刷新VRT文件

2.2 结果

下载的结果如下,影像信息已经更新到VRT文件中了: