RoBoard魔人的機器人日誌

2012/4/6

[RoBoRC最終回] 介紹程式碼demo

終於來到最終回了

而demo這個也是本魔認為最麻煩的一個

這邊有用到蠻複雜的結構

以及demo需要把之前好幾回的東西整合起來思考 ((因為它有init

總之來看看吧~

demo.h
#ifndef __DEMO_H
#define __DEMO_H

#include "defines.h"

#define CMD_MAXNAMELEN  (256)

typedef struct _FRM_NODE                  //frame節點
{
 int frmno;                     //編號
 unsigned long frm[32];                  //內容   32個PWM
 struct _FRM_NODE *next;                  //下一個節點
}FRM_NODE;

typedef struct _ACT_NODE                  //動作的節點
{
 int type;                     //型態
 int time;                     //時間
 int actno;                     //編號
 unsigned long *frm;
 union{                      //union型別   選一個用
  int frmno;                    //編號
  char *filename;                   //檔案名稱
 }data;
 struct _ACT_NODE *next;                  //下一個節點
}ACT_NODE;
//-- values for ACT_t.type
 #define  ACT_START   (0)
 #define  ACT_PAUSE   (1)
 #define  ACT_PLAYFRAMENO (2)
 #define  ACT_PLAYSND  (3)

typedef struct _CMD_NODE                  //指令的節點
{
 int command;                    //指令編號
 int actno;                     //動作的編號
 char name[CMD_MAXNAMELEN+1];                //指令名稱
 ACT_NODE *act;                    //對應到的動作結點
 struct _CMD_NODE *next;                  //下一個節點
}CMD_NODE;

typedef struct _CH_t                   //channel的節點
{
 int pin;                     //腳位編號
 int mode_idx;                    //模式
 int offset;                     //偏移值
}CH_t;

typedef struct {                    //主要架構

 int rbidx;                     
 int initact;                    
 ACT_NODE *initactnode;
 int initfrm;
 int initfrm_mode;
 unsigned long usedChannels;
 unsigned long *inithome;
 CH_t channel[32];

 int actidx;
 int actsize;
 ACT_NODE *actpool;
 ACT_NODE **acttable;

 int frmidx;
 int frmsize;
 FRM_NODE *frmpool;
 FRM_NODE **frmtable;

 int cmdidx;
 int cmdsize;
 CMD_NODE *cmdpool;
 CMD_NODE **cmdtable;

// int SND_maxNum; //unused at the moment

} DEF_t;
//-- value for initfrm_mode
#define INIT_FRM_FALSE (0)
#define INIT_FRM_TRUE (1)

#ifdef __cplusplus
extern "C" {
#endif

CMD_NODE *tool_FindCMDNode(CMD_NODE **table, int command, int size);
ACT_NODE *tool_FindACTNode(ACT_NODE **table, int actno, int size);

bool tool_InitCapture(CH_t *channel, unsigned long usedch, int mode_idx);
bool tool_InitDemo(DEF_t *def, char *dirname);
bool tool_InitReplay(DEF_t *def, char *filename, int replaytime, int mode_idx, int actno, unsigned long usedchannels);

#ifdef __cplusplus
}
#endif

#endif

demo.cpp
#include <math.h>
#include <stdlib.h>
#include "demo.h"
#include "parse.h"
#include "errcode.h"
#include "fileio.h"

static int prime(int n);
static int HashFun(int n, int base);

static ACT_NODE *SearchACT(ACT_NODE *node, int actno);
static CMD_NODE *SearchCMD(CMD_NODE *node, int cmd);
static FRM_NODE *SearchFRM(FRM_NODE *node, int frmno);

static int GetTotalACT(ACT_NODE *pool, int idx);
static int InsertACT(ACT_NODE ***table, ACT_NODE *pool, int total, int size);
static int InsertCMD(CMD_NODE ***table, CMD_NODE *pool, int total, int size);
static int InsertFRM(FRM_NODE ***table, FRM_NODE *pool, int total, int size);

static ACT_NODE *map_FindACTNode(ACT_NODE **table, int actno, int size);
static CMD_NODE *map_FindCMDNode(CMD_NODE **table, int command, int size);
static FRM_NODE *map_FindFRMNode(FRM_NODE **table, int frmno, int size);
static int map_MappingACT(FRM_NODE **table, ACT_NODE *actpool, int actidx, int size);
static int map_MappingCMD(ACT_NODE **table, CMD_NODE *cmdpool, int cmdidx, int size);
static int map_MappingDEF(DEF_t *def);

static void SetFrame(FRM_NODE *pool, CH_t *ch, int idx);

static int FRMToACT(DEF_t *def, char *filename, int actno, int time);

/* ==================  hash function ==================*/
static int prime(int n)                   //尋找比n大  且最接近n的質數
{
 int i, j, size, max;
 int *array;
 max = (int)sqrt((double)n) + 1;
 size = max * max;
 array = (int *)malloc(sizeof(int) * size);
 for(i = 0; i < size; i++)
  array[i] = 0;
 for(i = 2; i < max; i++){
  if(array[i] == 0){
   for(j = 2*i; j < size; j += i)
    array[j] = 1;
  }
 }
 for(i = n; i < size; i++){
  if(array[i] == 0)
   break;
 }
 free(array);
 return i;
}

static int HashFun(int n, int base)                //雜湊  取base次方 再mod base
{
 return (n ^ base) % base;
}

/* ==================  general function ==================*/
static ACT_NODE *SearchACT(ACT_NODE *node, int actno)           //尋找ACT_NODE內編號actno的節點
{
 while(node != NULL){
  if(node->actno == actno)
   break;
  node = node->next;
 }
 return node;
}

static CMD_NODE *SearchCMD(CMD_NODE *node, int cmd)            //尋找CMD_NODE內編號cmd的節點
{
 while(node != NULL){
  if(node->command == cmd)
   break;
  node = node->next;
 }
 return node;
}

/* ==================  insert function ==================*/
static FRM_NODE *SearchFRM(FRM_NODE *node, int frmno)           //尋找FRM_NODE內編號frmno的節點
{
 while(node != NULL){
  if(node->frmno == frmno)
   break;;
  node = node->next;
 }
 return node;
}


static int GetTotalACT(ACT_NODE *pool, int idx)             //得到action的總個數
{
 int i, total;
 total = 0;
 for(i = 0; i < idx - 1; i++){
  if(pool[i].type == ACT_START)
   total += 1;
 }
 return total;
}

static int InsertACT(ACT_NODE ***table, ACT_NODE *pool, int total, int size)     //建造ACT的表格
{
 int i, idx;
 if(size == 0)
  return SUCCESS;
 *table = (ACT_NODE **)malloc(sizeof(ACT_NODE *) * size);
 if(*table == NULL)
  return MEMORY_ERROR;
 for(i = 0; i < size; i++)
  (*table)[i] = NULL;
 for(i = 0; i < total - 1; i++){
  if(pool[i].type == ACT_START){
   idx = HashFun(pool[i].actno, size);
   if(SearchACT((*table)[idx], pool[i].actno) != NULL){
    errcode_SetErrACT(pool[i].actno);
    return MAP_REPEAT_ACTNO;
   }
   pool[i].next = (*table)[idx];
   (*table)[idx] = &pool[i];
  }
 }
 return SUCCESS;
}

static int InsertCMD(CMD_NODE ***table, CMD_NODE *pool, int total, int size)     //建造CMD的表格
{
 int i, idx;
 if(size == 0)
  return SUCCESS;
 *table = (CMD_NODE **)malloc(sizeof(CMD_NODE *) * size);
 if(*table == NULL)
  return MEMORY_ERROR;
 for(i = 0; i < size; i++)
  (*table)[i] = NULL;
 for(i = 0; i < total; i++){
  idx = HashFun(pool[i].command, size);
  if(SearchCMD((*table)[idx], pool[i].command) != NULL){
   errcode_SetErrCMD(pool[i].command);
   return MAP_REPEAT_CMD;
  }
  pool[i].next = (*table)[idx];
  (*table)[idx] = &pool[i];
 }
 return SUCCESS;
}

static int InsertFRM(FRM_NODE ***table, FRM_NODE *pool, int total, int size)     //建造FRM的表格
{
 int i, idx;
 if(size == 0)
  return SUCCESS;
 *table = (FRM_NODE **)malloc(sizeof(FRM_NODE *) * size);
 if(*table == NULL)
  return MEMORY_ERROR;
 for(i = 0; i < size; i++)
  (*table)[i] = NULL;
 for(i = 0; i < total; i++){
  idx = HashFun(pool[i].frmno, size);
  if(SearchFRM((*table)[idx], pool[i].frmno) != NULL){
   errcode_SetErrFRM(pool[i].frmno);
   return MAP_REPEAT_FRMNO;
  }
  pool[i].next = (*table)[idx];
  (*table)[idx] = &pool[i];
 }
 return SUCCESS;
}

static int InsertTable(DEF_t *def)                //計算table大小  以及創建table
{
 int status;
 def->actsize = prime((int)(GetTotalACT(def->actpool, (def->actidx)) * 1.5));
 def->cmdsize = prime((int)(def->cmdidx * 1.5));
 def->frmsize = prime((int)(def->frmidx * 1.5));
 status = InsertACT(&def->acttable, def->actpool, def->actidx, def->actsize);
 if(status == SUCCESS)
  status = InsertCMD(&def->cmdtable, def->cmdpool, def->cmdidx, def->cmdsize);
 if(status == SUCCESS)
  status = InsertFRM(&def->frmtable, def->frmpool, def->frmidx, def->frmsize);
 return status;
}

/* ==================  function for mapping  ==================*/
static ACT_NODE *map_FindACTNode(ACT_NODE **table, int actno, int size)       //回傳ACT table內的actno   若已有使用則回傳下一個
{
 ACT_NODE *p;
 int idx;
 if(table == NULL)
  return NULL;
 idx = HashFun(actno, size);
 p = SearchACT(table[idx], actno);
 if(p == NULL)
  return p;
 return p + 1;
}

static CMD_NODE *map_FindCMDNode(CMD_NODE **table, int command, int size)      //回傳CMD table內的command
{
 int idx;
 if(table == NULL)
  return NULL;
 idx = HashFun(command, size);
 return SearchCMD(table[idx], command);
}

static FRM_NODE *map_FindFRMNode(FRM_NODE **table, int frmno, int size)       //回傳FRM table內的frmno
{
 int idx;
 if(table == NULL)
  return NULL;
 idx = HashFun(frmno, size);
 return SearchFRM(table[idx], frmno);
}

static int map_MappingACT(FRM_NODE **table, ACT_NODE *actpool, int actidx, int size)   //mapping FRM編號
{
 int i;
 FRM_NODE *p;
 for(i = 0; i < actidx; i++){
  if(actpool[i].type == ACT_PLAYFRAMENO){
   p = map_FindFRMNode(table, actpool[i].data.frmno, size);
   if(p == NULL){
    errcode_SetErrFRM(actpool[i].data.frmno);
    return MAP_NOFINDFRM;
   }
   actpool[i].frm = p->frm;
  }
 }
 return SUCCESS;
}

static int map_MappingCMD(ACT_NODE **table, CMD_NODE *cmdpool, int cmdidx, int size)   //mapping act編號
{
 int i;
 ACT_NODE *p;
 for(i = 0; i < cmdidx; i++){
  p = map_FindACTNode(table, cmdpool[i].actno, size);
  if(p == NULL){
   errcode_SetErrACT(cmdpool[i].actno);
   return MAP_NOFINDACT;
  }
  cmdpool[i].act = p;
 }
 return SUCCESS;
}

static int map_MappingDEF(DEF_t *def)               //mapping  def的所有NODE
{
 FRM_NODE *p;
 int status;
 if(def->initfrm != -1){
  p = map_FindFRMNode(def->frmtable, def->initfrm, def->frmsize);
  if(p == NULL){
   errcode_SetErrFRM(def->initfrm);
   return MAP_NOFINDINITFRM;
  }
  def->inithome = p->frm;
 }
 if(def->initact != -1){
        def->initactnode = map_FindACTNode(def->acttable, def->initact, def->actsize);
  if(def->initactnode == NULL){
   errcode_SetErrACT(def->initact);
   return MAP_NOFINEINITACT;
  }
 }
 status = map_MappingACT(def->frmtable, def->actpool, def->actidx, def->frmsize);
 if(status == SUCCESS)
  status = map_MappingCMD(def->acttable, def->cmdpool, def->cmdidx, def->actsize);
 return status;
}

/* ==================  function for offset  ==================*/
static void SetFrame(FRM_NODE *pool, CH_t *ch, int idx)           //將偏移植算入frame
{
 int i, j;
 unsigned long temp[32];
 for(i = 0; i < idx; i++){
  for(j = 0; j < 32; j++)
   temp[j] = pool[i].frm[j];
  for(j = 0; j < 32; j++){
   if(ch[j].pin != -1)
    pool[i].frm[ch[j].pin] = temp[j] + ch[j].offset;
  }
 }
}

/* ==================  function for replay frame  ==================*/
int FRMToACT(DEF_t *def, char *filename, int actno, int time)         //設定一些預設值   replay mode用  
{
 FILEIO *fp;
    INI_ITEM_t item;
 ACT_NODE *act;
 int status = SUCCESS;
 fp = ini_FileOpen(filename);
 if(fp == NULL)
  return FRM_OFFSET + OPEN_FILE_FAIL;
 act = &def->actpool[def->actidx];
 act->type = ACT_START;
 act->actno = actno;
 status = tool_InsertACTPool(&def->actpool, &def->actidx);
 while ((status == SUCCESS) && (ini_ReadNextItem(fp, &item) != INI_FILEEND))
 {
  act = &def->actpool[def->actidx];
  switch(item.type)
        {
            case INI_GROUPTITLE:
    act->type = ACT_PLAYFRAMENO;
    act->time = time;
    status = tool_GetGroupFRM(item.itemname, &act->data.frmno);
    if(status == SUCCESS)
     status = tool_InsertACTPool(&def->actpool, &def->actidx);
                break;
        }
    }
 ini_FileClose(fp);
 act = &def->actpool[def->actidx];
 act->type = ACT_START;
 act->actno = -1;
 status = tool_InsertACTPool(&def->actpool, &def->actidx);
 return status;
}

/* ==================  tool function ==================*/
CMD_NODE *tool_FindCMDNode(CMD_NODE **table, int command, int size)
{
 return map_FindCMDNode(table, command, size);
}

ACT_NODE *tool_FindACTNode(ACT_NODE **table, int actno, int size)
{
 return map_FindACTNode(table, actno, size);
}

bool tool_InitCapture(CH_t *channel, unsigned long usedch, int mode_idx)      //init Capture mode
{
 int i;
 for(i = 0; i < 32; i++)
  channel[i].pin = -1;

 for(i = 0; i < 32; i++){
     if((usedch & (1L << i)) != 0){
            channel[i].pin = i;
            channel[i].offset = 0;
            channel[i].mode_idx = mode_idx;
       }
 }
 return true;
}

bool tool_InitReplay(DEF_t *def, char *filename, int replaytime, int mode_idx, int actno, unsigned long usedchannels) //init replay mode
{
 int i;
 int status;
 status = tool_InitDEF(def);
 for(i = 0; i < 32; i++){
  if((usedchannels & (1L << i)) != 0){
            def->channel[i].pin = i;
            def->channel[i].offset = 0;
            def->channel[i].mode_idx = mode_idx;
        }
 }
 if(status == SUCCESS)
  status = tool_ParseFile_FRM(def, filename);
 if(status == SUCCESS)
  status = FRMToACT(def, filename, actno, replaytime);
 if(status == SUCCESS)
  status = InsertTable(def);
 if(status == SUCCESS)
  status = map_MappingACT(def->frmtable, def->actpool, def->actidx, def->frmsize);
 if(status == SUCCESS)
  return true;
    errcode_ShowErr(status);
    return false;
}

bool tool_InitDemo(DEF_t *def, char *dirname)             //init demo mode
{
    int status;
 status = tool_InitDEF(def);
 if(status == SUCCESS)
  status = tool_ReadFile(dirname, def);
 SetFrame(def->frmpool, def->channel, def->frmidx);
 if(status == SUCCESS)
  status = InsertTable(def);
 if(status == SUCCESS)
        status = map_MappingDEF(def);
 if(status == SUCCESS)
        return true;
    errcode_ShowErr(status);
 return false;
}


基本上這樣子RoBoRC就告一段落了

相信學到這邊大家應該也都對RoBoRC有相當的了解!

以上!
Share:

0 留言:

張貼留言

技術提供:Blogger.

追蹤者