public bool UploadAction(int actionId)
        {

            if ((actionId < 0) || (actionId >= CONST.AI.MAX_ACTION))
            {
                UpdateInfo(String.Format("Invalid action ID: {0}", actionId), UTIL.InfoType.error);
                return false;
            }
            data.ActionInfo ai = actionTable.action[actionId];
            byte[] header = ai.GetData();
            // TODO: Error handling
            // For safety, wait 1s for writing header
            if (!V2_TryCommand(header, 1000))
            {
                UpdateInfo(String.Format("上传动作档 {0} 的头文件 出错, 动作可能已损坏, 请再次上传.", ai.actionCode), UTIL.InfoType.error);
                return false;
            }
            UInt16 poseCnt = ai.poseCnt;
            for (UInt16 pId = 0; pId < poseCnt; pId++)
            {
                byte[] poseData = ai.GetPoseData(pId);
                // For safety, wait 1s for writing data
                if (!V2_TryCommand(poseData, 1000))
                {
                    UpdateInfo(String.Format("上传动作档 {0} 出错, 动作可能已损坏, 请再次上传.", ai.actionCode), UTIL.InfoType.error);
                    return false;
                }
            }
            UpdateInfo(String.Format("Action {0} has been uploaded", ai.actionCode));

            return true;
        }
        private void SaveActionFile()
        {
            int actionId = GetSelectedActionId();

            if (actionId < 0)
            {
                return;
            }
            UpdateInfo();
            data.ActionInfo ai = UBT.actionTable.action[actionId];
            if (ai.actionFileExists && (!ai.poseLoaded))
            {
                MessageBox.Show("动作资料尚未下载到电脑, 请先 [下载动作]", "无法储存", MessageBoxButton.OK, MessageBoxImage.Asterisk);
                return;
            }
            SaveFileDialog saveFileDialog = new SaveFileDialog();

            saveFileDialog.Filter = CONST.ROBOT_ACTION_FILTER;
            if (saveFileDialog.ShowDialog() == true)
            {
                String fileName = saveFileDialog.FileName;
                try
                {
                    FileStream   fs = File.Create(fileName, 2048, FileOptions.None);
                    BinaryWriter bw = new BinaryWriter(fs);
                    bw.Write(ai.GetData());
                    for (UInt16 poseId = 0; poseId < ai.poseCnt; poseId++)
                    {
                        bw.Write(ai.GetPoseData(poseId));
                    }
                    bw.Close();
                    fs.Close();
                    UpdateInfo(String.Format("Action table saved to {0}", fileName));
                }
                catch (Exception ex)
                {
                    UpdateInfo(String.Format("Error saving to {0}: {1}", fileName, ex.Message), UTIL.InfoType.error);
                }
            }
        }