|
From: <he...@us...> - 2009-07-31 20:40:34
|
Revision: 82
http://simspark.svn.sourceforge.net/simspark/?rev=82&view=rev
Author: hedayat
Date: 2009-07-31 20:40:14 +0000 (Fri, 31 Jul 2009)
Log Message:
-----------
Added the HMDP plugin (By: N. Michael Mayer and Joschka)
Modified Paths:
--------------
trunk/rcssserver3d/ChangeLog
trunk/rcssserver3d/data/rsg/agent/nao/nao.rsg
trunk/rcssserver3d/plugin/soccer/CMakeLists.txt
trunk/rcssserver3d/plugin/soccer/export.cpp
Added Paths:
-----------
trunk/rcssserver3d/plugin/soccer/hmdp_effector/
trunk/rcssserver3d/plugin/soccer/hmdp_effector/hmdp_c/
trunk/rcssserver3d/plugin/soccer/hmdp_effector/hmdp_c/base.c
trunk/rcssserver3d/plugin/soccer/hmdp_effector/hmdp_c/base.h
trunk/rcssserver3d/plugin/soccer/hmdp_effector/hmdp_c/compatible.h
trunk/rcssserver3d/plugin/soccer/hmdp_effector/hmdp_c/hmdp_c.c
trunk/rcssserver3d/plugin/soccer/hmdp_effector/hmdp_c/hmdp_c.h
trunk/rcssserver3d/plugin/soccer/hmdp_effector/hmdp_c/sine_fixed.c
trunk/rcssserver3d/plugin/soccer/hmdp_effector/hmdp_c/sine_fixed.h
trunk/rcssserver3d/plugin/soccer/hmdp_effector/hmdpaction.h
trunk/rcssserver3d/plugin/soccer/hmdp_effector/hmdpeffector.cpp
trunk/rcssserver3d/plugin/soccer/hmdp_effector/hmdpeffector.h
trunk/rcssserver3d/plugin/soccer/hmdp_effector/hmdpeffector_c.cpp
trunk/rcssserver3d/plugin/soccer/hmdp_effector/hmdpperceptor.cpp
trunk/rcssserver3d/plugin/soccer/hmdp_effector/hmdpperceptor.h
trunk/rcssserver3d/plugin/soccer/hmdp_effector/hmdpperceptor_c.cpp
trunk/rcssserver3d/plugin/soccer/hmdp_effector/hmdpwrapper.cpp
trunk/rcssserver3d/plugin/soccer/hmdp_effector/naospecific.cpp
trunk/rcssserver3d/plugin/soccer/hmdp_effector/naospecific.h
Modified: trunk/rcssserver3d/ChangeLog
===================================================================
--- trunk/rcssserver3d/ChangeLog 2009-07-31 20:27:41 UTC (rev 81)
+++ trunk/rcssserver3d/ChangeLog 2009-07-31 20:40:14 UTC (rev 82)
@@ -1,3 +1,29 @@
+2009-07-31 Hedayat Vatankhah <he...@gr...>
+
+ * plugin/soccer/hmdp_effector/hmdp_c/sine_fixed.h:
+ * plugin/soccer/hmdp_effector/hmdp_c/sine_fixed.c:
+ * plugin/soccer/hmdp_effector/hmdp_c/hmdp_c.h:
+ * plugin/soccer/hmdp_effector/hmdp_c/hmdp_c.c:
+ * plugin/soccer/hmdp_effector/hmdp_c/compatible.h:
+ * plugin/soccer/hmdp_effector/hmdp_c/base.h:
+ * plugin/soccer/hmdp_effector/hmdp_c/base.c:
+ * plugin/soccer/hmdp_effector/naospecific.h:
+ * plugin/soccer/hmdp_effector/naospecific.cpp:
+ * plugin/soccer/hmdp_effector/hmdpwrapper.cpp:
+ * plugin/soccer/hmdp_effector/hmdpperceptor.h:
+ * plugin/soccer/hmdp_effector/hmdpperceptor.cpp:
+ * plugin/soccer/hmdp_effector/hmdpperceptor_c.cpp:
+ * plugin/soccer/hmdp_effector/hmdpeffector.h:
+ * plugin/soccer/hmdp_effector/hmdpeffector.cpp:
+ * plugin/soccer/hmdp_effector/hmdpeffector_c.cpp:
+ * plugin/soccer/hmdp_effector/hmdpaction.h:
+ * plugin/soccer/CMakeLists.txt:
+ * plugin/soccer/export.cpp:
+ * data/rsg/agent/nao/nao.rsg:
+ - added HMDP effector/perceptor. Thanks to N. Michael Mayer and Joschka.
+ - some code cleanup and formatting
+ - replacing the use of the obsolete function boost::make_shared()
+
2009-07-30 Hedayat Vatankhah <he...@gr...>
* plugin/CMakeLists.txt:
Modified: trunk/rcssserver3d/data/rsg/agent/nao/nao.rsg
===================================================================
--- trunk/rcssserver3d/data/rsg/agent/nao/nao.rsg 2009-07-31 20:27:41 UTC (rev 81)
+++ trunk/rcssserver3d/data/rsg/agent/nao/nao.rsg 2009-07-31 20:40:14 UTC (rev 82)
@@ -37,14 +37,14 @@
(switch $loadObj
(true
- (nd Transform
- (setLocalRotation -90 0 180)
- (nd StaticMesh
- (load 'models/naobody.obj')
- (setScale $TorsoLength $TorsoLength $TorsoLength)
- )
- )
+ (nd Transform
+ (setLocalRotation -90 0 180)
+ (nd StaticMesh
+ (load 'models/naobody.obj')
+ (setScale $TorsoLength $TorsoLength $TorsoLength)
+ )
)
+ )
(false
(importScene rsg/agent/nao/box_appearance.rsg $TorsoLength $TorsoWidth $TorsoHeight matGrey)
@@ -59,10 +59,10 @@
(importScene rsg/agent/nao/contactjointhandler.rsg)
)
- ;Install effectors and perceptors
+ ;Install effectors and perceptors
(nd StaticMeshInitEffector)
- (nd TimePerceptor)
+ (nd TimePerceptor)
(nd AgentState
(setName AgentState)
@@ -72,11 +72,14 @@
(nd GyroRatePerceptor (setName torso))
- (nd BeamEffector)
+ ;(nd HMDPPerceptor)
+ ;(nd HMDPEffector)
+ (nd BeamEffector)
+
(nd SayEffector)
- ;(nd VisionPerceptor
+ ;(nd VisionPerceptor
; (setSenseMyPos false)
; (setStaticSenseAxis false)
; (addNoise false))
Modified: trunk/rcssserver3d/plugin/soccer/CMakeLists.txt
===================================================================
--- trunk/rcssserver3d/plugin/soccer/CMakeLists.txt 2009-07-31 20:27:41 UTC (rev 81)
+++ trunk/rcssserver3d/plugin/soccer/CMakeLists.txt 2009-07-31 20:40:14 UTC (rev 82)
@@ -41,6 +41,10 @@
gametimeperceptor/gametimeperceptor.h
visionperceptor/visionperceptor.h
agentintegration/soccerbotbehavior.h
+ hmdp_effector/hmdpaction.h
+ hmdp_effector/hmdpeffector.h
+ hmdp_effector/hmdpperceptor.h
+ hmdp_effector/naospecific.h
)
set(soccer_LIB_SRCS
@@ -107,6 +111,12 @@
gametimeperceptor/gametimeperceptor_c.cpp
agentintegration/soccerbotbehavior.cpp
agentintegration/soccerbotbehavior_c.cpp
+ hmdp_effector/hmdpeffector_c.cpp
+ hmdp_effector/hmdpeffector.cpp
+ hmdp_effector/hmdpperceptor_c.cpp
+ hmdp_effector/hmdpperceptor.cpp
+ hmdp_effector/hmdpwrapper.cpp
+ hmdp_effector/naospecific.cpp
)
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${SPARK_INCLUDE_DIR}
Modified: trunk/rcssserver3d/plugin/soccer/export.cpp
===================================================================
--- trunk/rcssserver3d/plugin/soccer/export.cpp 2009-07-31 20:27:41 UTC (rev 81)
+++ trunk/rcssserver3d/plugin/soccer/export.cpp 2009-07-31 20:40:14 UTC (rev 82)
@@ -51,6 +51,8 @@
#include "hearperceptor/hearperceptor.h"
#include "gametimeperceptor/gametimeperceptor.h"
#include "agentintegration/soccerbotbehavior.h"
+#include "hmdp_effector/hmdpeffector.h"
+#include "hmdp_effector/hmdpperceptor.h"
ZEITGEIST_EXPORT_BEGIN()
ZEITGEIST_EXPORT(SoccerControlAspect);
@@ -84,5 +86,7 @@
ZEITGEIST_EXPORT(VisionPerceptor);
ZEITGEIST_EXPORT(GameTimePerceptor);
ZEITGEIST_EXPORT(SoccerbotBehavior);
+ ZEITGEIST_EXPORT(HMDPPerceptor);
+ ZEITGEIST_EXPORT(HMDPEffector);
ZEITGEIST_EXPORT_END()
Added: trunk/rcssserver3d/plugin/soccer/hmdp_effector/hmdp_c/base.c
===================================================================
--- trunk/rcssserver3d/plugin/soccer/hmdp_effector/hmdp_c/base.c (rev 0)
+++ trunk/rcssserver3d/plugin/soccer/hmdp_effector/hmdp_c/base.c 2009-07-31 20:40:14 UTC (rev 82)
@@ -0,0 +1,636 @@
+/***************************************************************************
+ * Base routines of the command parser (without the HMDP commands) *
+ * Part of the Microcontroller Basimplementation of HMDP *
+ * N. Michael Mayer, 2007 email: nm...@gm... *
+ * This part of the program is intended to be used in the micro-controller *
+ ***************************************************************************/
+
+/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*-
+
+ this file is part of rcssserver3D
+
+ Copyright (C) 2002,2003 Koblenz University
+ Copyright (C) 2003 RoboCup Soccer Server 3D Maintenance Group
+ Copyright (C) 2008 N. Michael Mayer, email: nm...@gm...
+
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+//
+
+#include "base.h"
+#include "hmdp_c.h"
+#include "compatible.h"
+
+Base_data *base_data; // pointer to current instantiation of the data
+
+
+void sendMesg(const char *str) //! uses sendByte to make messages...
+{
+ while (*str)
+ {
+ sendByte(*str);
+ str++;
+ }
+}
+
+void write_int(int in) //! write out integer to master
+{
+ char xx[] =
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ data2hex(8, in, xx);
+ sendMesg(xx);
+}
+
+void set_current_servo_pos_as_zero()
+{
+ int i;
+ init_servo_list();
+ for (i = 1; i <= base_data->servo_list_base[0]; ++i)
+
+ base_data->zero_pos_inits_feed[base_data->servo_list_base[i]]
+ = read_back_pos_set(base_data->servo_list_base[i]);
+ base_data->zero_pos_inits = &(base_data->zero_pos_inits_feed[0]);
+ sendMesg("Current zero pos is now zero\r\n");
+}
+
+void init_base()
+{
+ base_data->op_state = 0;
+ base_data->echo_on = 0;
+ base_data->bbase = 0;
+ init_servo_list(); /*! search for all servos */
+ //init_hmdl(); /*! in arm.c */
+ sendMesg("# HMDP 0.3 \n");
+}
+
+int servo_list_in_hex(char *li)
+{
+
+ init_servo_list();
+ int i;
+ for (i = 0; i <= base_data->servo_list_base[0]; ++i)
+ {
+ data2hex(2, base_data->servo_list_base[i], &li[2* i ]);
+ }
+ li[base_data->servo_list_base[0] * 2 + 2] = 0;
+ return 0;
+}
+
+void send_servo_list()
+{
+ char list[200];
+ servo_list_in_hex(list);
+
+ sendByte('!'); //!Data indikator
+
+ sendMesg(list);
+ sendByte(13);
+ sendByte(10);
+}
+
+int init_servo_list() //!gives back
+//!(size, id, id...)
+{
+
+ char i;
+ int pos = 1;
+ for (i = 0; i < 62; ++i)
+ {
+ if (read_back_id(i))
+ {
+ base_data->servo_list_base[pos] = i;
+ pos++;
+ }
+ }
+ base_data->servo_list_base[0] = pos - 1;
+ return 0;
+}
+;
+
+void eval_set_echo_on_off(const char in[])
+/*! >E command one can turn on/off the echo */
+{
+ if (in[1] == 'N')
+ base_data->echo_on = 0;
+ if (in[1] == 'F')
+ base_data->echo_on = -1;
+
+}
+;
+
+void eval_send_gen_message(const char in[])
+/*! >$ command allows direct access to the servos */
+{
+ int si = hex2data(2, in);
+ int i;
+ for (i = 0; i < si; i++)
+ {
+ char me = hex2data(2, in + 2 + 2* i );
+ sendBytetoMo(me);
+
+ };
+}
+;
+
+void eval_set_position_message(const char in[])
+/*! >P command sets servo to position */
+{
+ int servoid, value;
+ servoid = hex2data(2, in);
+ value = hex2data(4, in + 2);
+ value += base_data->zero_pos_inits[servoid]
+ - base_data->zero_pos_inits_feed[servoid];
+ send_servo_to_pos(servoid, value);
+}
+;
+
+void eval_set_min_max_message(const char in[])
+//! >M message -- for setting up min and max values
+{
+ int servoid, minvalue, maxvalue;
+ servoid = hex2data(2, in);
+ base_data->servo_min_val[servoid] = hex2data(4, in + 2);
+ base_data->servo_max_val[servoid] = hex2data(4, in + 6);
+ char eins[5];
+ eins[4] = 0;
+ sendMesg("\n");
+ data2hex(4, base_data->servo_min_val[servoid], eins);
+ sendMesg(eins);
+ data2hex(4, base_data->servo_max_val[servoid], eins);
+ sendMesg(eins);
+ sendMesg("\n");
+}
+;
+
+void eval_set_state_message(const char in[])
+//! >S message
+{
+ base_data->op_state = hex2data(2, in);
+
+ sendMesg("\r\n");
+ write_int(base_data->op_state);
+ sendMesg("\r\n");
+}
+;
+
+void eval_set_gain_message(const char in[])
+//! set gain for servo
+{
+ int servoid, value;
+ servoid = hex2data(2, in);
+ value = hex2data(2, &in[2]);
+ send_servo_to_gain(servoid, value);
+
+}
+;
+
+void eval_set_time(const char in[])
+//! set time
+{
+ long time = hex2data(8, in);
+ set_hmdl_time(time);
+}
+;
+
+void send_time()
+//! read time from HMDP and send it to the client
+{
+ char mes[12] =
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ data2hex(8, get_hmdl_time(), mes);
+ sendMesg("!");
+ sendMesg(mes);
+ sendMesg("\r\n");
+
+ data2hex(8, get_hmdl_time_inc(), mes);
+ sendMesg("inc: ");
+ sendMesg(mes);
+ sendMesg("\r\n");
+
+}
+;
+
+void eval_set_servo_on_off(const char in[])
+//! check for >ON or >OFF message both start with the the letter O
+{
+
+ int servoid;
+ sendMesg("in on off\n");
+ switch (in[0])
+ {
+ case 'N': //! >ON##
+
+ servoid = hex2data(2, &in[1]);
+ send_servo_on(servoid);
+ break;
+
+ default: //! >OFF##
+ servoid = hex2data(2, &in[2]);
+ send_servo_off(servoid);
+ break;
+ }
+
+}
+;
+
+void eval_get_jname(const char in[])
+/*! reads the name of the servo form the preprogrammed list defined in
+ compatible.h */
+{
+
+ int servoid, position, i;
+
+ sendByte('!'); //Data indikator
+
+ if (jointnames != NULL)
+ {
+
+ if (in[0] == 'v') //! all joints
+ {
+ //init_servo_list();
+ for (i = 0; i < base_data->servo_list_base[0]; ++i)
+ {
+
+ sendMesg(jointnames[i]);
+ sendByte(':');
+
+ };
+
+ }
+ else
+ {
+ servoid = hex2data(2, &in[0]);
+
+ sendMesg(jointnames[servoid]);
+
+ };
+ }
+ sendByte(13);
+ sendByte(10);
+
+}
+
+void eval_get_pos_message(const char in[])
+/* <P command read serv-pos from potis */
+{
+
+ int servoid, position, i;
+
+ sendByte('!'); //Data indikator
+
+ if (in[0] == 'v')
+ {
+ //init_servo_list();
+ for (i = 0; i < base_data->servo_list_base[0]; ++i)
+ {
+ servoid = base_data->servo_list_base[i + 1];
+ position = read_back_pos(servoid);
+ position -= base_data->zero_pos_inits[servoid]
+ - base_data->zero_pos_inits_feed[servoid]; //ACHTUNG
+
+ char xx[] =
+ { 0, 0, 0, 0, 0 };
+ data2hex(4, position, xx);
+ sendMesg(xx);
+
+ };
+ sendByte(13);
+ sendByte(10);
+
+ }
+ else
+ {
+ servoid = hex2data(2, &in[0]);
+ position = read_back_pos(servoid);
+ position -= base_data->zero_pos_inits[servoid]
+ - base_data->zero_pos_inits_feed[servoid]; //ACHTUNG
+
+ char xx[] =
+ { 0, 0, 0, 0, 13, 0 };
+ data2hex(4, position, xx);
+ sendMesg(xx);
+ //uart0SendByte('*');
+ sendByte(13);
+ sendByte(10);
+ };
+}
+;
+
+void eval_get_pos_set_message(const char in[])
+/*! <R get target value */
+{
+
+ int servoid, position, i;
+
+ sendByte('!'); //Data indikator
+
+ if (in[0] == 'v')
+ {
+ init_servo_list();
+ for (i = 0; i < base_data->servo_list_base[0]; ++i)
+ {
+ servoid = base_data->servo_list_base[i + 1];
+ position = read_back_pos_set(servoid);
+ char xx[] =
+ { 0, 0, 0, 0, 0 };
+ data2hex(4, position, xx);
+ sendMesg(xx);
+
+ };
+ //uart0SendByte('*');
+ sendByte(13);
+ sendByte(10);
+
+ }
+ else
+ {
+
+ servoid = hex2data(2, &in[0]);
+ position = read_back_pos_set(servoid);
+ char xx[] =
+ { 0, 0, 0, 0, 13, 0 };
+ data2hex(4, position, xx);
+ sendMesg(xx);
+ sendByte(13);
+ sendByte(10);
+ }
+}
+;
+
+void send_zero_pos()
+{
+
+ int i;
+ sendByte('!');
+ for (i = 0; i < base_data->servo_list_base[0]; ++i)
+ {
+ unsigned char servoid = base_data->servo_list_base[i + 1];
+ int zeropos = base_data->zero_pos_inits_feed[servoid]; //ACHTUNG DEBUG
+
+ char xx[] =
+ { 0, 0, 0, 0, 0 };
+ data2hex(4, zeropos, xx);
+ sendMesg(xx);
+
+ };
+ sendByte(13);
+ sendByte(10);
+
+}
+; // send zero pos feed
+
+
+void plastic_state()
+/*! timer call for plastic state */
+{
+ init_servo_list();
+ int i;
+ int j, val;
+ for (i = 1; i <= base_data->servo_list_base[0]; ++i)
+ {
+
+ j = base_data->servo_list_base[i];
+ val = read_back_pos(j);
+ send_servo_to_pos(j, val);
+ };
+}
+;
+
+/* first level parser for base.c commands (<..., >...., @....)*/
+int eval_seq_base(const char in[])
+{
+
+ int found_command = 0;
+ found_command = -1;
+ switch (in[0])
+ {
+ case '>':
+ disableIRQ();
+
+ switch (in[1])
+ {
+ case '$':
+ eval_send_gen_message(&in[2]); /* >$ (gen messg command */
+ case 'S':
+ eval_set_state_message(&in[2]); /* >S command */
+ break;
+ case 'P':
+ eval_set_position_message(&in[2]); /* >P command */
+ break;
+ case 'G':
+ eval_set_gain_message(&in[2]); /* >G command */
+ break;
+ case 'O':
+ eval_set_servo_on_off(&in[2]); /* >O command */
+ break;
+ case 'M':
+ eval_set_min_max_message(&in[2]); /* >M command */
+ break;
+ case 'T':
+ eval_set_time(&in[2]); /* >T command */
+ break;
+ case 'E':
+ eval_set_echo_on_off(&in[2]); /* >E command */
+ break;
+ case 'Z':
+ set_current_servo_pos_as_zero();
+ break;
+ }
+ enableIRQ();
+ break;
+ case '<':
+
+ switch (in[1])
+ {
+ case 'N':
+ disableIRQ();
+ eval_get_jname(&in[2]); /* <N command: get the names of the servos */
+ break;
+ case 'P':
+ disableIRQ();
+ eval_get_pos_message(&in[2]); /* <P command */
+ break;
+ case 'R':
+ disableIRQ();
+ eval_get_pos_set_message(&in[2]); /* <R command */
+ break;
+ case 'L':
+ disableIRQ();
+ send_servo_list(); /* <L command servo list*/
+ break;
+ case 'T':
+ disableIRQ();
+ send_time();
+ break;
+ case 'Z':
+ send_zero_pos(); // send zero pos feed
+ break;
+
+ }
+ enableIRQ();
+ default:
+ found_command = -1;
+ break;
+ }
+ return found_command;
+}
+;
+
+/* sending motion to servo ...*/
+
+void send_hmdp_motion_to_servo()
+{
+ int i;
+ for (i = 0; i < base_data->servo_list_base[0]; ++i)
+ {
+
+ int ID = base_data->servo_list_base[i + 1];
+ int pos = base_data->zero_pos_inits[(int) base_data->servo_list_base[i
+ + 1]] + get_hmdl_servo_out(i);
+
+ send_servo_to_pos((int) base_data->servo_list_base[i + 1], pos);
+ };
+
+}
+;
+
+/*! interrupt routine for plastic state */
+void inter_routine_state_2()
+{
+ plastic_state();
+}
+;
+
+/*! interrupt routine for HMDP runnung */
+void inter_routine_state_1()
+{
+ // if ((get_hmdl_time_inc()!=0))
+ // {
+ calc_next_timer_value();
+ send_hmdp_motion_to_servo();
+ motion_machine(calc_next_timer_value());
+
+}
+;
+
+/*! main interrupt routine */
+void inter_routine_base()
+{
+ if (base_data->op_state == 1)
+ inter_routine_state_1();
+ if (base_data->op_state == 2)
+ inter_routine_state_2();
+
+}
+;
+
+int main_eval(char *buff)
+{
+
+ if (eval_seq_base(buff) == -1)
+ {
+ //sendMesg ("\n");
+ eval_seq(buff); // HMDP parser in hmdp_c.c
+
+ }
+ return 0;
+}
+
+//! main parser
+int parse_one_line()
+{
+ char in[3];
+ in[0] = 0;
+ in[1] = 0;
+ int buff_c = 0;
+ int a = 0;
+
+ while (a != 13)
+ {
+ // led1_off();
+ a = readByte();
+ ;
+ if (a != -1)
+ {
+ // led1_on();
+ base_data->buff[base_data->bbase + buff_c] = a;
+ buff_c++;
+ in[0] = a;
+ if (base_data->echo_on == 0)
+ sendByte(a);
+
+ };
+ };
+
+ if (buff_c > 5) //! Checksum feature
+ {
+ if ((base_data->buff[base_data->bbase + buff_c - 4] == 'C')
+ && (base_data->buff[base_data->bbase + buff_c - 3] == 'S'))
+ {
+ int sum = 0;
+ int i;
+ for (i = 0; i < buff_c - 4; ++i)
+ sum += base_data->buff[base_data->bbase + i];
+ sum %= 15;
+ int sum2 = hex2data(1, &(base_data->buff[base_data->bbase + buff_c
+ - 2]));
+ if (sum == sum2)
+ {
+ sendMesg("\r\n*\r\n");
+ }
+ else
+ {
+ sendMesg("\r\nE\r\n");
+ };
+ buff_c -= 3;
+
+ };
+ };
+ if (buff_c > 1) //! Long message feature
+ {
+ if (base_data->buff[base_data->bbase + buff_c - 2] == '&')
+ {
+ base_data->bbase += buff_c - 2;
+ sendMesg("add line \n");
+ }
+ else
+ {
+ base_data->buff[base_data->bbase + buff_c] = 13;
+ base_data->buff[base_data->bbase + buff_c + 1] = 0;
+
+ base_data->bbase = 0;
+
+ }
+
+ }
+ else
+ {
+
+ base_data->buff[base_data->bbase + buff_c] = 13;
+ base_data->buff[base_data->bbase + buff_c + 1] = 0;
+ base_data->bbase = 0;
+ }
+ if (base_data->bbase == 0)
+ {
+ sendMesg("\r\n");
+
+ main_eval(base_data->buff); // see base.c
+ clearBuffer();
+ };
+
+}
+;
+
Property changes on: trunk/rcssserver3d/plugin/soccer/hmdp_effector/hmdp_c/base.c
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/rcssserver3d/plugin/soccer/hmdp_effector/hmdp_c/base.h
===================================================================
--- trunk/rcssserver3d/plugin/soccer/hmdp_effector/hmdp_c/base.h (rev 0)
+++ trunk/rcssserver3d/plugin/soccer/hmdp_effector/hmdp_c/base.h 2009-07-31 20:40:14 UTC (rev 82)
@@ -0,0 +1,73 @@
+/***************************************************************************
+ * base.h for the Harmonic Motion Description Protocol (HMDP) *
+ * N. Michael Mayer, 2007 email: nm...@gm... *
+ * This part of the program is intended to be used in the micro-controller *
+ ***************************************************************************/
+
+/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*-
+
+ this file is part of rcssserver3D
+
+ Copyright (C) 2002,2003 Koblenz University
+ Copyright (C) 2003 RoboCup Soccer Server 3D Maintenance Group
+ Copyright (C) 2008 N. Michael Mayer, email: nm...@gm...
+
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __HMDP_BASE__
+#define __HMDP_BASE__
+
+#define MAX_ALLOWED_SERVOS 64
+#define MAX_PARSER_BUFFER_SIZE 200
+
+typedef struct
+{
+ /*! instantiation of the state variable
+
+ */
+ int op_state; // main state variable HMDP off=0, HMDP on =1, plastic =2
+ int servo_min_val[MAX_ALLOWED_SERVOS + 1]; // sets a min and a max value for each joint
+ int servo_max_val[MAX_ALLOWED_SERVOS + 1];
+ char servo_list_base[MAX_ALLOWED_SERVOS + 1]; // reserved memory for the joint ids
+ int *zero_pos_inits; // pointer to current zero positions
+ int zero_pos_inits_feed[MAX_ALLOWED_SERVOS + 1]; // ram list of the zero positions
+ int bbase; // pointer to the current position in the parser buffer
+ char buff[MAX_PARSER_BUFFER_SIZE]; // parser buffer
+ int echo_on; // echo flag -- for terminal communication
+
+} Base_data; // all "global" data put for base.c
+
+
+// functions in base.c
+
+
+void init_base();
+int parse_one_line();
+void inter_routine_base();
+
+int init_servo_list();
+int servo_list_in_hex(char *li);
+int eval_seq_base(const char in[]);
+void send_hmdp_motion_to_servo();
+void write_int(int in);
+
+extern char jointnames[MAX_ALLOWED_SERVOS][8];
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#endif
Property changes on: trunk/rcssserver3d/plugin/soccer/hmdp_effector/hmdp_c/base.h
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/rcssserver3d/plugin/soccer/hmdp_effector/hmdp_c/compatible.h
===================================================================
--- trunk/rcssserver3d/plugin/soccer/hmdp_effector/hmdp_c/compatible.h (rev 0)
+++ trunk/rcssserver3d/plugin/soccer/hmdp_effector/hmdp_c/compatible.h 2009-07-31 20:40:14 UTC (rev 82)
@@ -0,0 +1,92 @@
+/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*-
+
+ The functions names in this header have to be implmented for each microcontroller individually
+
+ Copyright (C) 2008 N. Michael Mayer, nm...@gm...
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+//! HMDP Compatibility Layer:
+
+#ifndef ___COMPATIBLE_RR___
+#define ___COMPATIBLE_RR___
+
+//! This is the set of functions and constants used by the hmdp_c.c and base.c functions. They have to be implemented for each robot individually
+
+//! Interrupt related functions
+
+// #1
+void disableIRQ();
+// #2
+void enableIRQ();
+
+// !Communication over with the the client
+// #3
+int sendByte(int data);
+// #4
+int readByte();
+// #5
+void clearBuffer();
+
+//! possibly useful to allow direct communication between client and servos using the >$ command
+// #6
+int sendBytetoMo(int);
+
+//! These commands have to be implemented to control the servos
+//! For all servos it is assummed that 0 corresponds to the minimal value and 4096 corresponds to the maximal value
+
+// #7
+void send_servo_off(int ID); // ! turn servo off
+// #8
+void send_servo_on(int ID); // ! turn servo on
+// #9
+void send_servo_to_pos(int ID, int pos); // ! commands
+// #10
+void send_servo_to_gain(int ID, int gain);
+
+// #11
+int read_back_pos(int ID); // ! read current servo pos from poti value
+// #12
+int read_back_pos_set(int ID); // ! read targert position from servo
+// #13
+int read_back_id(int ID); // ! check if a servo with the particular ID is present
+
+
+/*! for all things mentioned below this point:
+ HMDP internally counts the servo from lower numbers to higher numbers thus a robot with servo
+ IDs 1,3,8,15 internally has the IDs 0,1,2,3
+ the arrays: jointnames[][8]; and zer_pos_inits_feed */
+
+// #14
+extern char jointnames[][8]; // ! names of the joints
+// ! can be read out by: <Nxx and used by tools e.g. for transferring motion patterns from one robot to another
+/*! Naming Conventions: NNXYPD[D] NN: Limb name that is: HE: Head, RA: right arm RL: Right leg, etc.
+ X number of the major joint position counted from the body center: hip, shoulder, neck = 1;
+ knee, elbow = 2;
+ foot, wrist = 3;
+ Y number of the hingjoint within the joint -- differs in dependence of the design
+ P parity -- if the robot executes the same motion according to reflection symmetry, i.e. all R become L if the motion stays
+ the same with parity +
+ is inverted in the case of parity -
+ D direction in Pitch (P), Roll (R), Yaw (Y), diagonal joints may use double letters e.g. PY
+ numbering convention: IF THE ROBOT HAS GAPS BETWEEN SERVO NUMBERS:
+ */
+
+// #15
+extern int zero_pos_inits_feed[];
+/*! Zero positions i.e. the values that should be send to the servos of the robot to set it into an initial posture,
+ a posture from which the motions deviate. In some robots it is necessary */
+
+#endif // ___COMPATIBLE_RR___
Property changes on: trunk/rcssserver3d/plugin/soccer/hmdp_effector/hmdp_c/compatible.h
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/rcssserver3d/plugin/soccer/hmdp_effector/hmdp_c/hmdp_c.c
===================================================================
--- trunk/rcssserver3d/plugin/soccer/hmdp_effector/hmdp_c/hmdp_c.c (rev 0)
+++ trunk/rcssserver3d/plugin/soccer/hmdp_effector/hmdp_c/hmdp_c.c 2009-07-31 20:40:14 UTC (rev 82)
@@ -0,0 +1,977 @@
+#include "hmdp_c.h"
+#include "sine_fixed.h"
+
+Hmdl *hmdl; // hook for a pointer to all data
+
+
+/*! Util routines to convert integers to hex strings and vice versa */
+
+int hex2data(short size_v, const char res[])
+{
+
+ int k;
+ int data;
+ data = 0;
+
+ for (k = 0; k < size_v; k++)
+ {
+
+ data *= 16;
+ switch (res[k])
+
+ {
+ case '0':
+ break;
+ case '1':
+ data += 1;
+ break;
+ case '2':
+ data += 2;
+ break;
+ case '3':
+ data += 3;
+ break;
+ case '4':
+ data += 4;
+ break;
+ case '5':
+ data += 5;
+ break;
+ case '6':
+ data += 6;
+ break;
+ case '7':
+ data += 7;
+ break;
+ case '8':
+ data += 8;
+ break;
+ case '9':
+ data += 9;
+ break;
+ case 'a':
+ data += 10;
+ break;
+ case 'b':
+ data += 11;
+ break;
+ case 'c':
+ data += 12;
+ break;
+ case 'd':
+ data += 13;
+ break;
+ case 'e':
+ data += 14;
+ break;
+ case 'f':
+ data += 15;
+ break;
+
+ }
+
+ };
+ return data;
+}
+;
+
+void data2hex(short size_v, const int dat, char res[])
+{
+
+ int k;
+ int data = dat;
+ for (k = size_v - 1; k >= 0; k--)
+ {
+
+ switch (data % 16)
+
+ {
+ case 0:
+ res[k] = '0';
+ break;
+ case 1:
+ res[k] = '1';
+ break;
+ case 2:
+ res[k] = '2';
+ break;
+ case 3:
+ res[k] = '3';
+ break;
+ case 4:
+ res[k] = '4';
+ break;
+ case 5:
+ res[k] = '5';
+ break;
+ case 6:
+ res[k] = '6';
+ break;
+ case 7:
+ res[k] = '7';
+ break;
+ case 8:
+ res[k] = '8';
+ break;
+ case 9:
+ res[k] = '9';
+ break;
+ case 10:
+ res[k] = 'a';
+ break;
+ case 11:
+ res[k] = 'b';
+ break;
+ case 12:
+ res[k] = 'c';
+ break;
+ case 13:
+ res[k] = 'd';
+ break;
+ case 14:
+ res[k] = 'e';
+ break;
+ case 15:
+ res[k] = 'f';
+ break;
+
+ }
+ data /= 16;
+ };
+
+}
+;
+
+void set_hmdl_time(long time)
+{
+ hmdl->time = time;
+}
+;
+
+long get_hmdl_time()
+{
+ return hmdl->time;
+}
+;
+
+long get_hmdl_time_inc()
+{
+ return hmdl->time_inc;
+}
+;
+
+short get_hmdl_servo_out(int i)
+{
+ return cfloat2int(hmdl->positions_to_set[i]);
+}
+;
+
+void write_cfloat(struct c_float *in)
+{
+
+ struct c_f_hex in_hex = c_float2hex(*in);
+ sendMesg(in_hex.stri);
+
+}
+
+#define INTERVAL 50 /* num of ms for the timer to go off */
+
+/* function prototype */
+void motion_control(int);
+
+/*
+ * global variables
+ */
+
+/* struct Hmdl hmdl;*/
+
+struct c_f_hex c_float2hex(struct c_float in)
+{
+ short sign, esign, i;
+ struct c_f_hex ret;
+ for (i = 0; i < 15; ++i)
+ ret.stri[i] = 0;
+
+ if (in.mantisse < 0)
+ {
+ ret.stri[0] = '-';
+ sign = -1;
+ }
+ else
+ {
+ sign = 1;
+ ret.stri[0] = '+';
+ };
+
+ if (in.exponent < 0)
+ {
+ ret.stri[9] = '-';
+ esign = -1;
+ }
+ else
+ {
+ esign = 1;
+ ret.stri[9] = '+';
+ };
+
+ data2hex(8, sign * in.mantisse, &ret.stri[1]);
+ /*ret.stri[9]='^';*/
+
+ data2hex(2, esign * in.exponent, &ret.stri[10]);
+
+ return ret;
+}
+;
+
+struct c_float mult_cc(struct c_float a, struct c_float b)
+{
+ struct c_float c;
+ int sign_c = 1;
+
+ if (a.mantisse < 0)
+ {
+ sign_c = -1;
+ a.mantisse = -a.mantisse;
+ }
+
+ if (b.mantisse < 0)
+ {
+ sign_c = -sign_c;
+ b.mantisse = -b.mantisse;
+ }
+
+ a.mantisse = a.mantisse >> (INT_MAXE / 2);
+ b.mantisse = b.mantisse >> (INT_MAXE / 2);
+
+ c.exponent = a.exponent + b.exponent;
+ c.mantisse = a.mantisse * b.mantisse * sign_c;
+
+ if (c_abs(c.mantisse) < INT_MAXX)
+ {
+ c.exponent--;
+ c.mantisse = c.mantisse << 1;
+ };
+
+ return c;
+}
+;
+
+int cfloat2int(struct c_float a)
+{
+ int r;
+ if (a.mantisse > 0)
+ r = a.mantisse >> (INT_MAXE - a.exponent);
+ else
+ {
+ r = -1* ( (-a.mantisse)>>(INT_MAXE-a.exponent));
+ };
+ return r;
+};
+
+struct c_float hex2c_float(const char in[])
+{
+ struct c_float ret;
+ short sign, esign;
+ if (in[0] == '-')
+ sign = -1;
+ else if (in[0] == '+')
+ sign = +1;
+
+ if (in[9] == '-')
+ esign = -1;
+ else if (in[9] == '+')
+ esign = +1;
+
+ ret.mantisse = sign * hex2data(8, &in[1]);
+ ret.exponent = esign * hex2data(2, &in[10]);
+ return ret;
+}
+
+int lo2(int in)
+//! returns rough integer logarithm of in
+{
+ if (in >= 2048)
+ return 11;
+ if (in >= 1024)
+ return 10;
+ if (in >= 512)
+ return 9;
+ if (in >= 256)
+ return 8;
+ if (in >= 128)
+ return 7;
+ if (in >= 64)
+ return 6;
+ if (in >= 32)
+ return 5;
+ if (in >= 16)
+ return 4;
+ if (in >= 8)
+ return 3;
+ if (in >= 4)
+ return 2;
+ if (in >= 2)
+ return 1;
+ if (in < 2)
+ return 0;
+}
+;
+
+struct c_float c_f_sum(struct c_float a[], int size)
+//! sum of size c_floats
+{
+ int i, max, lsize;
+ lsize = lo2(size);
+ struct c_float result;
+ max = 0;
+ result.mantisse = 0;
+
+ for (i = 0; i < size; ++i)
+ if (a[i].exponent > max)
+ max = a[i].exponent;
+
+ for (i = 0; i < size; ++i)
+ {
+ result.mantisse += (a[i].mantisse >> (max - a[i].exponent + lsize));
+ };
+
+ result.exponent = max + lsize;
+ return result;
+}
+;
+
+int c_abs(int in)
+//! absolut value of integer
+{
+ if (in > 0)
+ return in;
+ else
+ return -in;
+}
+;
+
+struct c_float c_f_add(struct c_float s1, struct c_float s2)
+//! add 2 c_floats
+{
+ int i, max, lsize;
+ struct c_float result;
+ max = 0;
+ result.mantisse = 0;
+
+ max = s1.exponent;
+ if (s2.exponent > max)
+ max = s2.exponent;
+
+ if (s1.mantisse < 0)
+ result.mantisse -= ((-s1.mantisse) >> (max - s1.exponent + 1));
+ else
+ result.mantisse += ((s1.mantisse) >> (max - s1.exponent + 1));
+
+ if (s2.mantisse < 0)
+ result.mantisse -= (-s2.mantisse >> (max - s2.exponent + 1));
+ else
+ result.mantisse += (s2.mantisse >> (max - s2.exponent + 1));
+
+ result.exponent = max + 1;
+ if (c_abs(result.mantisse) < INT_MAXX)
+ {
+ result.exponent--;
+ if (result.mantisse > 0)
+ result.mantisse = result.mantisse << 1;
+ else
+ result.mantisse = -1* ( (-result.mantisse) <<1);
+ };
+
+ return result;
+ };
+
+struct c_float mult_c_sinus(struct c_float a, int d)
+//! multiply routine for sinus input c_float * sinus
+{
+ struct c_float c;
+
+ int sign_c = 1;
+
+ if (a.mantisse < 0)
+ {
+ sign_c = -1;
+ a.mantisse = -a.mantisse;
+ }
+
+ if (d < 0)
+ {
+ sign_c = -sign_c;
+ d = -d;
+ }
+
+ a.mantisse = a.mantisse >> (INT_MAXE / 2);
+ d = d >> (INT_MAXE / 2);
+
+ c.exponent = a.exponent;
+ c.mantisse = a.mantisse * d * sign_c;
+
+ return c;
+}
+;
+
+struct c_float mult_cc_sinus(struct c_float a, struct c_float b, int d)
+//! multiply 2 c_floats with one sinus
+{
+ struct c_float c;
+ int sign_c = 1;
+
+ if (a.mantisse < 0)
+ {
+ sign_c = -1;
+ a.mantisse = -a.mantisse;
+ }
+
+ if (d < 0)
+ {
+ sign_c = -sign_c;
+ d = -d;
+ }
+
+ if (b.mantisse < 0)
+ {
+ sign_c = -sign_c;
+ b.mantisse = -b.mantisse;
+ }
+
+ a.mantisse = a.mantisse >> (2*INT_MAXE / 3);
+ b.mantisse = b.mantisse >> (2*INT_MAXE / 3);
+ d = d >> (2*INT_MAXE / 3);
+
+ c.exponent = a.exponent + b.exponent;
+ c.mantisse = a.mantisse * b.mantisse * d * sign_c;
+
+ if (c_abs(c.mantisse) < INT_MAXX)
+ {
+ c.exponent--;
+ if (c.mantisse > 0)
+ c.mantisse = c.mantisse << 1;
+ else
+ c.mantisse = -1* ( (-c.mantisse) <<1);
+ };
+
+ return c;
+ };
+
+struct c_float set_c_float_zero()
+// returns a c_float = 0
+{
+ struct c_float a;
+ a.mantisse = 0;
+ a.exponent = 0;
+ return a;
+}
+
+struct c_float fade_in(struct c_float a, struct c_float b, long t_a, long t_b,
+ long t)
+//! provides fading in for motion patterns (in a linear -- ramp like manner)
+{
+
+ int max_man;
+ struct c_float c;
+ max_man = a.exponent;
+ int sign_a, sign_b;
+ if (a.mantisse >= 0)
+ {
+ sign_a = 1;
+ }
+ else
+ {
+ sign_a = -1;
+ a.mantisse = -a.mantisse;
+ };
+
+ if (b.mantisse >= 0)
+ {
+ sign_b = 1;
+ }
+ else
+ {
+ sign_b = -1;
+ b.mantisse = -b.mantisse;
+ };
+
+ if (max_man < b.exponent)
+ max_man = b.exponent;
+
+ long long diff = sign_b * (b.mantisse >> (max_man - b.exponent)) - sign_a
+ * (a.mantisse >> (max_man - a.exponent));
+ diff *= (t - t_a);
+ diff /= (t_b - t_a);
+
+ c.exponent = max_man;
+ c.mantisse = sign_a * a.mantisse + diff;
+
+ return c;
+}
+;
+
+void motion_machine(unsigned int time)
+/*! interpolation using direct access to the hmdl structure */
+{
+
+ int i, k, l;
+ struct c_float y, sine_amp, cos_amp;
+ struct c_float amp;
+ struct c_float *coeffs;
+
+ /*! iterate over the servos and sum all values for the active motion patterns
+ -> superposition */
+ for (i = 0; i < MAX_SERVOS; ++i)
+ {
+ hmdl->positions_to_set[i] = set_c_float_zero(); // init servo_list
+
+ /*! loop over all motion patterns, see which ones should be active */
+ for (k = 0; k < MAX_MPS; ++k)
+ {
+ /*! skip pattern if amplitude is 0 or not active */
+ if (!(hmdl->mp[k].active))
+
+ {
+ continue;
+ }
+
+ coeffs = hmdl->mp[k].pp->sv[i].s_position;
+
+ if (time < hmdl->mp[k].start_0)
+ amp = hmdl->mp[k].A_old;
+ else if (time >= hmdl->mp[k].start_1)
+ amp = hmdl->mp[k].A_new;
+ else
+ amp = fade_in(hmdl->mp[k].A_old, hmdl->mp[k].A_new,
+ hmdl->mp[k].start_0, hmdl->mp[k].start_1, time);
+
+ /*if (hmdl->mp[k].end_0!=0)
+ {
+ if (time > hmdl->mp[k].start_1)
+ {
+ hmdl->mp[k].start_0=hmdl->mp[k].end_0;
+ hmdl->mp[k].start_1=hmdl->mp[k].end_1;
+
+ hmdl->mp[k].end_0=0;
+ hmdl->mp[k].end_1=0;
+ hmdl->mp[k].A_old=hmdl->mp[k].A_new;
+ hmdl->mp[k].A_new=set_c_float_zero();
+ };
+ };*/
+
+ if (hmdl->mp[k].end_0 != 0)
+ {
+ if (time > hmdl->mp[k].end_0)
+ {
+ if (time > hmdl->mp[k].end_1)
+ {
+ //
+ amp = set_c_float_zero();
+ // hmdl->mp[k].active=0;
+ }
+
+ else
+ {
+ amp = fade_in(hmdl->mp[k].A_new, set_c_float_zero(),
+ hmdl->mp[k].end_0, hmdl->mp[k].end_1, time);
+
+ };
+
+ };
+ };
+
+ //amp = hmdl->mp[k].A_curr;
+ //if (i==20)
+ // {write_int(cfloat2int(amp)); DMESG(" : ");}
+
+ y = mult_cc(amp, coeffs[0]);
+ //y = coeffs[0];
+ //if (i==20) {
+ // write_int(cfloat2int(y)); DMESG(" : ");}
+
+
+ for (l = 0; l < (MAX_COEFFS - 1) / 2; ++l)
+ {
+ y = c_f_add(y, mult_cc_sinus(amp, coeffs[2* l + 1], sin_fixed(
+ ((time - hmdl->mp[k].offset) * hmdl->mp[k].pp->wlqs_top[l])
+ / hmdl->mp[k].pp->wlqs_bot[l])));
+
+ y = c_f_add(y, mult_cc_sinus(amp, coeffs[2* l + 2], cos_fixed(
+ ((time - hmdl->mp[k].offset) * hmdl->mp[k].pp->wlqs_top[l])
+ / hmdl->mp[k].pp->wlqs_bot[l])));
+ };
+
+ hmdl->positions_to_set[i] = c_f_add(y, hmdl->positions_to_set[i]);
+
+ };
+ };
+}
+;
+
+int calc_next_timer_value()
+//! wrapper for time
+{
+ hmdl->time += hmdl->time_inc;
+ return hmdl->time;
+}
+
+void eval_set_time_message(const char in[])
+// TS HMDP command similar to >T command but also increment can be set
+{
+ hmdl->time = hex2data(MAX_TIME_DIGITS, in);
+ hmdl->time_max = hex2data(MAX_TIME_DIGITS, &in[MAX_TIME_DIGITS]);
+ hmdl->time_inc = hex2data(MAX_TIME_DIGITS, &in[2*MAX_TIME_DIGITS]);
+ //timer_running=0;
+ write_int(hmdl->time);
+ sendMesg("\r\n");
+
+}
+;
+
+void eval_set_alarm_point(const char in[])
+// not implelemented so far
+{
+
+}
+;
+
+void eval_use_pattern_message(const char in[])
+//! PU command
+{
+ int patternid, curr;
+ patternid = hex2data(MAX_ID_DIGITS, in);
+
+ hmdl->mp[patternid].start_0 = hex2data(MAX_TIME_DIGITS, &in[MAX_ID_DIGITS]);
+ hmdl->mp[patternid].start_1 = hex2data(MAX_TIME_DIGITS, &in[MAX_ID_DIGITS
+ + MAX_TIME_DIGITS]);
+ hmdl->mp[patternid].offset = hex2data(MAX_TIME_DIGITS,
+ &in[MAX_ID_DIGITS + 2*MAX_TIME_DIGITS]);
+
+ hmdl->mp[patternid].end_0 = 0;
+ hmdl->mp[patternid].end_1 = 0;
+
+ curr = MAX_ID_DIGITS + 3*MAX_TIME_DIGITS;
+
+ hmdl->mp[patternid].A_old = hmdl->mp[patternid].A_new;
+ hmdl->mp[patternid].A_new = hex2c_float(&in[curr]);
+
+ hmdl->mp[patternid].active = 1;
+
+}
+;
+
+void eval_use_short_pattern_message(const char in[])
+//! PP command - shorter PU message
+//
+{
+ int patternid, curr;
+ patternid = hex2data(MAX_ID_DIGITS, in);
+
+ hmdl->mp[patternid].start_0 = 0;
+ hmdl->mp[patternid].start_1 = 0;
+ hmdl->mp[patternid].end_0 = 0;
+ hmdl->mp[patternid].end_1 = 0;
+ hmdl->mp[patternid].offset = 0;
+
+ hmdl->mp[patternid].A_old = hmdl->mp[patternid].A_new;
+ hmdl->mp[patternid].A_new.mantisse = 0x40000000;
+ hmdl->mp[patternid].A_new.exponent = 0;
+ hmdl->mp[patternid].active = 1;
+
+}
+;
+
+void eval_use_pattern_message_with_end(const char in[])
+//! PY sending a pattern with the ramp end
+{
+ int patternid, curr;
+ patternid = hex2data(MAX_ID_DIGITS, in);
+
+ hmdl->mp[patternid].A_old = set_c_float_zero();
+ hmdl->mp[patternid].A_new = set_c_float_zero();
+
+ hmdl->mp[patternid].start_0 = hex2data(MAX_TIME_DIGITS, &in[MAX_ID_DIGITS]);
+ hmdl->mp[patternid].start_1 = hex2data(MAX_TIME_DIGITS, &in[MAX_ID_DIGITS
+ + MAX_TIME_DIGITS]);
+ hmdl->mp[patternid].end_0 = hex2data(MAX_TIME_DIGITS,
+ &in[MAX_ID_DIGITS + 2*MAX_TIME_DIGITS]);
+ hmdl->mp[patternid].end_1 = hex2data(MAX_TIME_DIGITS,
+ &in[MAX_ID_DIGITS + 3*MAX_TIME_DIGITS]);
+ hmdl->mp[patternid].offset = hex2data(MAX_TIME_DIGITS,
+ &in[MAX_ID_DIGITS + 4*MAX_TIME_DIGITS]);
+ /*printf (" on sh 2 :%d %d\n", hmdl->mp[patternid].start_0,
+ hmdl->mp[patternid].start_1);*/
+
+ curr = MAX_ID_DIGITS + 5*MAX_TIME_DIGITS;
+
+ hmdl->mp[patternid].A_old = hmdl->mp[patternid].A_new;
+ hmdl->mp[patternid].A_new = hex2c_float(&in[curr]);
+
+ hmdl->mp[patternid].active = 1;
+
+}
+;
+
+void eval_set_servo_coeff_message(const char in[])
+{
+ int patternid, servoid, curr;
+ patternid = hex2data(MAX_ID_DIGITS, in);
+ servoid = hex2data(MAX_ID_DIGITS, &in[MAX_ID_DIGITS]);
+ curr = 2*MAX_ID_DIGITS;
+ int i = 0;
+ while ((in[curr] != 'X') && (in[curr] != 0) && (i < MAX_COEFFS))
+ {
+ hmdl->mp[patternid].pp->sv[servoid].s_position[i] = hex2c_float(
+ &in[curr]);
+ write_cfloat(&hmdl->mp[patternid].pp->sv[servoid].s_position[i]);
+ sendMesg("\r\n");
+ write_int(i);
+ sendMesg("\r\n");
+
+ i++;
+ curr += C_FLOAT_LENGTH;
+ };
+
+}
+;
+
+void eval_set_servo_small_coeff_message(const char in[])
+{
+ int patternid, servoid, coeffid, curr;
+ patternid = hex2data(MAX_ID_DIGITS, in);
+ servoid = hex2data(MAX_ID_DIGITS, &in[MAX_ID_DIGITS]);
+ coeffid = hex2data(MAX_ID_DIGITS, &in[2*MAX_ID_DIGITS]);
+ hmdl->mp[patternid].pp->sv[servoid].s_position[coeffid]
+ = hex2c_float(&in[3*MAX_ID_DIGITS]);
+}
+;
+
+//long long i;
+
+void eval_new_pattern_message(const char in[])
+{
+ int id, wp_number, counter, i, j;
+
+ /* get number */
+ id = hex2data(MAX_ID_DIGITS, in);
+ wp_number = hex2data(MAX_COE_DIGITS, &in[MAX_ID_DIGITS]);
+
+ counter = MAX_ID_DIGITS + MAX_COE_DIGITS;
+ for (i = 0; i < MAX_COEFFS; ++i)
+ for (j = 0; j < MAX_SERVOS; ++j)
+ {
+ hmdl->mp[id].pp->sv[j].s_position[i].mantisse = 0;
+ hmdl->mp[id].pp->sv[j].s_position[i].exponent = 0;
+ };
+
+ for (i = 0; i < (MAX_COEFFS - 1) / 2; ++i)
+ {
+ hmdl->mp[id].pp->wlqs_top[i] = 0;
+ hmdl->mp[id].pp->wlqs_bot[i] = 1;
+
+ };
+
+ for (i = 0; i < (wp_number - 1) / 2; ++i)
+ {
+ hmdl->mp[id].pp->wlqs_top[i] = hex2data(MAX_WLQ_DIGITS, &in[counter]);
+ counter += MAX_WLQ_DIGITS;
+ hmdl->mp[id].pp->wlqs_bot[i] = hex2data(MAX_WLQ_DIGITS, &in[counter]);
+ counter += MAX_WLQ_DIGITS;
+
+ /* DEBUG */
+ // printf ("MC: coeffs top %d bot %d \n", hmdl->mp[id].pp->wlqs_top[i],
+ // hmdl->mp[id].pp->wlqs_bot[i]);
+
+ };
+
+ /* DEBUG */
+ //intf("MC: Setting new pattern for number %d\n", id);
+}
+;
+
+void init_hmdl()
+{
+ int i, j, k, l, p;
+
+ /*
+ * inititialize HDML structure
+ */
+
+ /* motion patterns */
+
+ for (i = 0; i < MAX_MPS_IN_RAM; ++i)
+ {
+ hmdl->mp[i].pp = &(hmdl->mpp_in_ram[i]);
+ hmdl->mp[i].pp->ID_prop = 8888 + i;
+
+ for (j = 0; j < (MAX_COEFFS - 1) / 2; ++j)
+ {
+ hmdl->mp[i].pp->wlqs_top[j] = 0;
+ hmdl->mp[i].pp->wlqs_bot[j] = 1;
+ };
+
+ for (j = 0; j < MAX_SERVOS; j++)
+ {
+ for (k = 0; k < MAX_COEFFS; k++)
+ {
+ hmdl->mp[i].pp->sv[j].s_position[k].mantisse = 0;
+ hmdl->mp[i].pp->sv[j].s_position[k].exponent = 0;
+ };
+
+ };
+
+ };
+
+ /*for (i=MAX_MPS_IN_RAM;i<MAX_MPS;i++) // meant for motion patterns in flash
+ hmdl->mp[i].pp = 0x00058000 + 0x00000800*(i-MAX_MPS_IN_RAM);
+
+ for (i=0;i<MAX_MPS;++i)
+ {
+
+ hmdl->mp[i].A_old.mantisse=0;
+ hmdl->mp[i].A_old.exponent=0;
+ hmdl->mp[i].A_new.mantisse=0;
+ hmdl->mp[i].A_new.exponent=0;
+
+ hmdl->mp[i].start_0 = 0;
+ hmdl->mp[i].start_1 = 0;
+ hmdl->mp[i].updated = 0;
+ hmdl->mp[i].active = 0;
+ };*/// until here
+
+
+ hmdl->time = 0;
+ hmdl->time_max = 0;
+ hmdl->time_inc = 1;
+
+ /* positions to set */
+ for (p = 0; p < MAX_SERVOS; ++p)
+ {
+ hmdl->positions_to_set[p].exponent = 0;
+ hmdl->positions_to_set[p].mantisse = 0;
+ }
+
+}
+
+void eval_get_current_sine_val(const char in[])
+{
+ int patternid, freqid;
+ unsigned int retval;
+ patternid = hex2data(MAX_ID_DIGITS, in);
+ freqid = hex2data(MAX_ID_DIGITS, in);
+
+ retval = sin_fixed((hmdl->time) * hmdl->mp[patternid].pp->wlqs_top[freqid]
+ / hmdl->mp[patternid].pp->wlqs_bot[freqid]);
+ retval /= 100000;
+
+ sendMesg("current value:\r\n");
+ write_int(retval);
+ sendMesg("\r\n");
+ sendMesg("wlqs_top:\r\n");
+ write_int(hmdl->mp[patternid].pp->wlqs_top[freqid]);
+ sendMesg("\r\n");
+
+}
+;
+
+void eval_seq(const char in[])
+{
+
+ switch (in[0])
+ {
+ case 'P':
+ switch (in[1])
+ {
+ case 'N':
+ eval_new_pattern_message(&in[2]); // PN command
+ break;
+ case 'S':
+ eval_set_servo_coeff_message(&in[2]); // PS command
+ break;
+ case 'I':
+ eval_set_servo_small_coeff_message(&in[2]);
+ // PS command
+ break;
+ case 'U':
+ eval_use_pattern_message(&in[2]); // PU command
+ break;
+ case 'P':
+ eval_use_short_pattern_message(&in[2]); // PU command
+ break;
+ case 'Y':
+ eval_use_pattern_message_with_end(&in[2]); // PY command
+
+ break;
+ }
+ break;
+ case 'T':
+ switch (in[1])
+ {
+ case 'S':
+ eval_set_time_message(&in[2]); // TS command
+ break;
+ }
+
+ break;
+ case '?':
+ switch (in[1])
+ {
+ case 'S':
+ eval_get_current_sine_val(&in[2]);
+ break;
+
+ }
+ break;
+
+ }
+}
+;
+
+struct c_float interpolate_rational_c_float( /*Real amplitude interpolation*/
+int size_c, struct c_float amp, int time, struct c_float coeffs[],
+ unsigned int frequencies_up[],
+ unsigned int frequencies_bottom[])
+{
+ int l;
+ struct c_float y;
+ y = mult_cc(amp, coeffs[0]);
+
+ for (l = 0; l < (size_c - 1) / 2; ++l)
+ {
+ y = c_f_add(y, mult_cc_sinus(amp, coeffs[2* l + 1], sin_fixed((time
+ * frequencies_up[l]) / frequencies_bottom[l])));
+
+ y = c_f_add(y, mult_cc_sinus(amp, coeffs[2* l + 2], cos_fixed((time
+ * frequencies_up[l]) / frequencies_bottom[l])));
+ };
+
+ return y;
+
+}
+;
+
+struct c_float interpolate_c_float_phase(
+/*Amplitude is rotational matrix (complex) */
+int size_c, struct c_float amp[], int time, struct c_float coeffs[],
+ unsigned int frequencies[])
+{
+ int i;
+ struct c_float y, sine_amp, cos_amp;
+ y = mult_cc(amp[0], coeffs[0]);
+ for (i = 0; i < size_c / 2; i++)
+ {
+ sine_amp = c_f_add(mult_cc(amp[2], coeffs[2* i + 2]), mult_cc(amp[3],
+ coeffs[2* i + 1]));
+ cos_amp = c_f_add(mult_cc(amp[0], coeffs[2* i + 2]), mult_cc(amp[1],
+ coeffs[2* i + 1]));
+
+ y
+ = c_f_add(y, mult_c_sinus(sine_amp, sin_fixed(time
+ * frequencies[i])));
+ y = c_f_add(y, mult_c_sinus(cos_amp, cos_fixed(time * frequencies[i])));
+ };
+
+ return y;
+}
+;
+
Property changes on: trunk/rcssserver3d/plugin/soccer/hmdp_effector/hmdp_c/hmdp_c.c
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/rcssserver3d/plugin/soccer/hmdp_effector/hmdp_c/hmdp_c.h
===================================================================
--- trunk/rcssserver3d/plugin/soccer/hmdp_effector/hmdp_c/hmdp_c.h (rev 0)
+++ trunk/rcssserver3d/plugin/soccer/hmdp_effector/hmdp_c/hmdp_c.h 2009-07-31 20:40:14 UTC (rev 82)
@@ -0,0 +1,196 @@
+/***************************************************************************
+ * Header for the Harmonic Motion Description Protocol (HMDP) *
+ * N. Michael Mayer, 2007 email: nm...@gm... *
+ * This part of the program is intended to be used in the micro-controller *
+ ***************************************************************************/
+
+/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*-
+
+ this file is part of rcssserver3D
+
+ Copyright (C) 2002,2003 Koblenz University
+ Copyright (C) 2003 RoboCup Soccer Server 3D Maintenance Group
+ Copyright (C) 2008 N. Michael Mayer, email: nm...@gm...
+
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef ___HMDP_C___
+#define ___HMDP_C___
+
+struct c_float /* Float Wrapper */
+{
+ int mantisse;
+ short exponent;
+};
+
+struct c_f_hex
+{
+ char stri[15];
+};
+
+#define C_FLOAT_LENGTH (1+8+1+2) // SMMMMMMMMSEEY Sign, Exponent, Mantisse, Y=Y
+#define HMDL_MESSAGE_START "";
+/*! Header for all HMDL Messages when they are sent over the serial bus */
+
+#define MAX_WLQ_DIGITS 6
+/*! Number of hex digits reserved for the Frequencies = wavelengthquarters: WLQs */
+
+#define MAX_TIME_DIGITS 8
+
+#define MAX_COE_DIGITS 2
+/*! Hex Digits reverved for the number of coeffieicnets */
+
+#define MAX_ID_DIGITS 2
+/*! Maximal Number of Digits of the ID; Since the ID can be up to 127 this
+ means it is 2 */
+
+#define MAX_MPS 67
+#define MAX_MPS_IN_RAM 67
+/*! Maximal numbers of Motion patterns that can be present
+ at one time in the SH2*/
+#define MAX_SERVOS 22
+/*! Maximal number of servos */
+#define MAX_COEFFS 11
+/*!maximal number of coefficients*/
+#define MAX_ALARM_POINTS 1
+/*! maximal number of points were the status can be readout */
+
+#define TM_BUFFER_SIZE 1024
+/*! Size of the List of timer tasks, see @... commands */
+
+struct motion_pattern_servo
+/* Structure that contains data about the motion of one servo */
+{
+ struct c_float s_position[MAX_COEFFS];
+ /*struct c_float s_gain [MAX_COEFFS];*/
+};
+
+struct motion_pattern_props
+{
+ int wlqs_top[((MAX_COEFFS - 1) / 2)];
+ int wlqs_bot[((MAX_COEFFS - 1) / 2)];
+ struct motion_pattern_servo sv[MAX_SERVOS];
+ int ID_prop;
+};
+
+struct motion_pattern
+/* Structure that contains all data necessary for a specific motion pattern */
+{
+ struct motion_pattern_props *pp; //[1];
+ struct c_float A_new;
+ struct c_float A_old;
+ // struct c_float A_curr;
+ unsigned long start_0, start_1, end_0, end_1,// interpolate amplitude from start_0 to start_1
+ offset, // used to offset the pattern when started
+ offsetoverflow; // used to save the offset after the time wraps around
+ unsigned short updated, // pattern was changed
+ active; // pattern is active
+
+};
+
+struct message_alarm_clock
+{
+ unsigned long alarm_time;
+ void (*callf)();
+};
+
+typedef struct
+/* all data necessary for the complete harmonic motion description
+ language */
+{
+ unsigned long time, time_max, time_inc;
+ struct motion_pattern mp[MAX_MPS]; /* -> sv -> s_position */
+ struct message_alarm_clock alarm[MAX_ALARM_POINTS];
+ struct c_float positions_to_set[MAX_SERVOS];
+ struct motion_pattern_props mpp_in_ram[MAX_MPS_IN_RAM];
+
+} Hmdl;
+
+struct c_f_hex c_float2hex(struct c_float in);
+struct c_float float2cfloat(float a);
+struct c_float mult_cc(struct c_float a, struct c_float b);
+// multiply 2 c_floats
+struct c_float mult_ccc(struct c_float a, struct c_float b, struct c_float d);
+// multiply 3 c-fs
+struct c_float mult_cc_sinus(struct c_float a, struct c_float b, int d);
+// multiply 2 c-fs and the output of the sine_fixed routine (d parameter)
+struct c_float mult_c_sinus(struct c_float a, int d);
+// multiply c-f and the output of the sine_fixed routine (d parameter)
+
+
+struct c_float c_f_sum(struct c_float a[], int size);
+// sum a list of c_floats
+struct c_float hex2c_float(const char in[]);
+// read a cfloat from ascii with special format
+int cfloat2int(struct c_float a);
+// make a cloat to int (cut behind the point = floor)
+/*struct c_float cfloat2int (int a);*/
+// interpolation function
+/* 1. parameter size, 2. Amplitude over all, 3. time, 4. Coeffs array of c_float,
+ 5. frequencies (frequency * time -> parameter to sine_fixed routines*/
+
+struct c_float interpolate_rational_c_float( /*Real amplitude interpolation*/
+int size_c, struct c_float amp, int time, struct c_float coeffs[],
+ unsigned int frequencies_up[],
+ unsigned int frequencies_bottom[]);
+
+struct c_float interpolate_c_float(int, struct c_float, int,
+ struct c_float coeffs[],
+ unsigned int frequencies[]);
+
+struct c_float interpolate_c_float_phase(int, struct c_float amps[], int,
+ struct c_float coeffs[],
+ unsigned int frequencies[]);
+
+void eval_seq(const char in[]);
+/*! input interpreter of HMDP*/
+
+/* Inititalize variables, start timer, etc */
+void init_hmdl();
+
+/* Clean up */
+void end_hmdl();
+
+/*! Handle situtations when the time needs to wrap around since time_max has
+ been reached. Offset values have to be saved for the motion patterns, and
+ the update flag needs to be set */
+void handle_overflow(void);
+
+void motion_machine(unsigned int time);
+
+/*! motion control - time management+*
+
+ This function is triggered by an interrupt and call the motion m...
[truncated message content] |