关键词:OSDK, waypoint mission, sample
一、概述:
航点任务是OSDK中应用较为广泛的的一个功能,OSDK4.1版本中兼容了waypoint mission(waypoint v1),waypoint v2功能以及热点任务功能,当前最新的机型M300仅支持waypoint v2,
但是M210 v2系列机型又不支持waypoint v2,热点任务没有两个版本,两种机型均可使用。感觉版本兼容性做的还是有点麻烦,这篇文章简单记录一下OSDK waypoint v1(mission)功能部分的sample,后面再继续分享waypoint v2部分。
首先贴一下相关官网链接:
文档:
https://developer.dji.com/cn/document/d625d3fc-ad52-4db4-9409-6406cea669b4
github 链接:
https://www.github.com/dji-sdk/Onboard-SDK/tree/4.1/sample/platform/linux/missions
二、看sample:
waypoint v1 sample主文件为main.cpp
两个demo选项,
a ------ 航点任务示例代码
b ------ 热点任务示例代码
这篇文章尝试直接在Sample代码中关键步骤中添加注释说明,以便阅读代码:
bool runWaypointMission(Vehicle* vehicle, uint8_t numWaypoints, int responseTimeout)
{
//订阅功能初始化,订阅功能需要适配机型。
if (!vehicle->isM100() && !vehicle->isLegacyM600())
{
if (!setUpSubscription(vehicle, responseTimeout))
{
std::cout << "Failed to set up Subscription!" << std::endl;
return false;
}
sleep(1);
}
//初始化waypoint参数
// Waypoint Mission : Initialization
WayPointInitSettings fdata;
setWaypointInitDefaults(&fdata);
fdata.indexNumber = numWaypoints + 1; // We add 1 to get the aircarft back to the start.
float64_t increment = 0.000001;
float32_t start_alt = 10;
//初始化missionManager模块
ACK::ErrorCode initAck = vehicle->missionManager->init(DJI_MISSION_TYPE::WAYPOINT, responseTimeout, &fdata);
//注册回调接口,航点任务运行状态就是通过此回调接口抛出。有发现DJI Assistant2上不勾选地面站状态推送时,将不会触发回调函数。若回调未触发可以检查一下DJI Assistant2 OSDK界面。
vehicle->missionManager->wpMission->setWaypointEventCallback(&WaypointEventCallBack,vehicle);
if (ACK::getError(initAck))
{
ACK::getErrorCodeMessage(initAck, __func__);
}
vehicle->missionManager->printInfo();
std::cout << "Initializing Waypoint Mission..\n";
//生成航点任务,这部分可以根据自己实际需要来设计航点任务,demo是通过航点任务个数计算出了一个多边形的航线。
// Waypoint Mission: Create Waypoints
std::vector<WayPointSettings> generatedWaypts = createWaypoints(vehicle, numWaypoints, increment, start_alt);
std::cout << "Creating Waypoints..\n";
//将生成的航点一起打包上传至飞控
// Waypoint Mission: Upload the waypoints
uploadWaypoints(vehicle, generatedWaypts, responseTimeout);
std::cout << "Uploading Waypoints..\n";
//下发指令给飞控,开始执行已经上传给飞控的航点及任务
// Waypoint Mission: Start
ACK::ErrorCode startAck =vehicle->missionManager->wpMission->start(responseTimeout);
if (ACK::getError(startAck))
{
ACK::getErrorCodeMessage(initAck, __func__);
}
else
{
std::cout << "Starting Waypoint Mission.\n";
}
OsdkOsal_TaskSleepMs(120000);
// Cleanup before return. The mission isn't done yet, but it doesn't need any
// more input from our side.
if (!vehicle->isM100() && !vehicle->isLegacyM600())
{
return teardownSubscription(vehicle, DEFAULT_PACKAGE_INDEX,
responseTimeout);
}
return true;
}
三、小结:
简单总结一下,航点任务即是开发者应用端预先规划好需要飞行的航点,一并打包上传至飞控,发送start指令后,飞控开始执行已经上传的任务。
1、最少需要两个航点,M210任务最多99个
2、两个航点间的距离范围为 0.5m ~ 2000m
3、传给飞控的航点经纬度参数为弧度值,如果传角度值将会无法正常上传
航点动作actions
航点动作为飞机到达航点后执行的动作,比如悬停等待,调整姿态,云台控制、拍照等动作,仅支持OSDK本身定义的actions动作:
typedef enum WaypointActionTypeFormat
{
WP_ACTION_STAY = 0, /*!< no action.uint of action parameter:ms*/
WP_ACTION_SIMPLE_SHOT = 1, /*!< take picture action.action parameters Action parameter have no effect.limit time:6s*/
WP_ACTION_VIDEO_START = 2, /*!< start take video action.action parameters Action parameter have no effect.limit time:6s*/
WP_ACTION_VIDEO_STOP = 3, /*!< stop video action.action parameters Action parameter have no effect.limit time:6s*/
WP_ACTION_CRAFT_YAW = 4, /*!< craft control yaw action.uint of action parameter:degree. range:-180 ~ 180*/
WP_ACTION_GIMBAL_PITCH = 5, /*!< gimbal control pitch action.uint of action parameter:degree. range:-90 ~ 0*/
} WaypointActionTypeFormat;
顺便再看看代码中航点动作的添加:
void
setWaypointDefaults(WayPointSettings* wp)
{
wp->damping = 0; //与traceMode对应,traceMode设置为1时,最小值为0.2
wp->yaw = 0;
wp->gimbalPitch = 0;
wp->turnMode = 0; //设置顺时针还是逆时针
wp->hasAction = 1; //有上传action时,任务时需要设置为1
wp->actionTimeLimit = 100; //航点执行任务的时间,任务较多时间设置太短,任务可能执行不完
wp->actionNumber = 5;
wp->actionRepeat = 1; //任务执行次数,设置为0不执行。
//for (int i = 0; i < 2; ++i)
{
wp->commandList[0] = WP_ACTION_GIMBAL_PITCH;
wp->commandParameter[0] = 0;
wp->commandList[1] = WP_ACTION_GIMBAL_PITCH;
wp->commandParameter[0] = -90;
}
}
这个参数设置是可以在每个航点任务中添加的,参数参考上面的注释说明,即设置该航点参数后,达到该航点将会执行对应的动作。如上所示代码表示到达航点后先执行将云台pitch置0,然后向下90度。
如果每个航点都调用此设置,将会在到达每一个航点执行相同的动作。
航点任务基本功能也就是这些了,了解这些后再结合demo代码跑一下功能基本也没啥问题了。waypoint v2功能上与上述功能基本上算是一致的,但是接口变化较大,对原有功能进行了一些拓展,后面再单独
写篇文章跟一跟。在这继续看下这个demo中的b选项,也就是热点任务功能。
同样先上代码:
bool
runHotpointMission(int initialRadius)
{
ACK::ErrorCode ack;
if (v->getFwVersion() != Version::M100_31)
{
if (!setUpSubscription(v))
{
printf("Failed to set up Subscription!\n");
return false;
}
}
// Global position retrieved via subscription
Telemetry::TypeMap<Telemetry::TOPIC_GPS_FUSED>::type subscribeGPosition;
// Global position retrieved via broadcast
Telemetry::GlobalPosition broadcastGPosition;
// Hotpoint Mission Initialize
v->missionManager->init(HOTPOINT, 1, NULL); //初始化missionmanager热点任务功能
v->missionManager->printInfo();
if (v->getFwVersion() != Version::M100_31)
{
subscribeGPosition = v->subscribe->getValue<Telemetry::TOPIC_GPS_FUSED>();
v->missionManager->hpMission->setHotPoint(
subscribeGPosition.longitude, subscribeGPosition.latitude, initialRadius); //订阅获取当前坐标并设置为热点坐标以及环绕半径
}
else
{
broadcastGPosition = v->broadcast->getGlobalPosition();
v->missionManager->hpMission->setHotPoint(
broadcastGPosition.longitude, broadcastGPosition.latitude, initialRadius); //广播方式获取GPS坐标,M100机型
}
// Takeoff
monitoredTakeOff(); //与航点任务有点区别,需要先调用takeoff
// Start
printf("Start with default rotation rate: 15 deg/s");
v->missionManager->hpMission->start(); //启动热点任务
delay_nms(500);
/*ack = waitForAck();
if (ACK::getError(ack))
{
ACK::getErrorCodeMessage(ack, __func__);
ACK::ErrorCode ack =
v->subscribe->removePackage(pkgIndex);
if (ACK::getError(ack))
{
printf("Error unsubscribing; please restart the drone/FC to get "
"back to a clean state.\n");
}
return false;
}*/
delay_nms(20000);
// Pause
printf("Pause for 5s\n");
v->missionManager->hpMission->pause();
delay_nms(5000);
/*ack = waitForACK();
if (ACK::getError(ack))
{
ACK::getErrorCodeMessage(ack, __func__);
}*/
// Resume
printf("Resume\n");
v->missionManager->hpMission->resume(); //热点任务过程中可以通过pause和resume来停止或回复执行
delay_nms(4000);
/*ack = waitForACK();
if (ACK::getError(ack))
{
ACK::getErrorCodeMessage(ack, __func__);
}*/
// Update radius, no ACK
printf("Update radius to 1.5x: new radius = %0.3f\n", 1.5 * initialRadius);
v->missionManager->hpMission->updateRadius(1.5 * initialRadius);
delay_nms(10000);
// Update velocity (yawRate), no ACK
printf("Update hotpoint rotation rate: new rate = 5 deg/s\n");
HotpointMission::YawRate yawRateStruct;
yawRateStruct.clockwise = 1;
yawRateStruct.yawRate = 5;
v->missionManager->hpMission->updateYawRate(yawRateStruct); //通过提供的API调整飞行设定
delay_nms(10000);
// Give it a bit more time to finish a circle
delay_nms(20000);
// Stop
printf("Stop\n");
v->missionManager->hpMission->stop();
delay_nms(1000);
printf("Land\n");
// Free existing packages
if (v->getFwVersion() != Version::M100_31)
{
v->subscribe->removePackage(DEFAULT_PACKAGE_INDEX);
delay_nms(3000);
/*ack = waitForACK();
if (ACK::getError(ack))
{
printf("Error unsubscribing; please restart the drone/FC to get back "
"to a clean state.\n");
}*/
}
return monitoredLanding() ? true : false;
}
小结:
提供的sample比较简单,该功能也比较简单,没有太多需要记录的,无非通过提供的API来发送指令并对任务进行设定。还可以通过getHotpointSettings来获取设定
具体的API可以参考:
dji_hotpoint.hpp
评论
0 条评论
请登录写评论。