Dynamixel  2.9.5
RoadNarrows Robotics Dynamixel Package
dynashell_main.cxx
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // Package: Dynamixel
4 //
5 // Program: dynashell
6 //
7 // File: dynashell_main.c
8 //
9 /*! \file
10  *
11  * $LastChangedDate: 2015-01-12 10:56:06 -0700 (Mon, 12 Jan 2015) $
12  * $Rev: 3845 $
13  *
14  * \brief RoadNarrows simple Dynamixel shell using the RoadNarrows Dynamixel
15  * library.
16  *
17  * \author Robin Knight (robin.knight@roadnarrows.com)
18  *
19  * \copyright
20  * \h_copy 2011-2017. RoadNarrows LLC.\n
21  * http://www.roadnarrows.com\n
22  * All Rights Reserved
23  */
24 /*
25  * @EulaBegin@
26  *
27  * Unless otherwise stated explicitly, all materials contained are copyrighted
28  * and may not be used without RoadNarrows LLC's written consent,
29  * except as provided in these terms and conditions or in the copyright
30  * notice (documents and software) or other proprietary notice provided with
31  * the relevant materials.
32  *
33  * IN NO EVENT SHALL THE AUTHOR, ROADNARROWS LLC, OR ANY
34  * MEMBERS/EMPLOYEES/CONTRACTORS OF ROADNARROWS OR DISTRIBUTORS OF THIS SOFTWARE
35  * BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR
36  * CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
37  * DOCUMENTATION, EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN
38  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39  *
40  * THE AUTHORS AND ROADNARROWS LLC SPECIFICALLY DISCLAIM ANY WARRANTIES,
41  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
42  * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN
43  * "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO
44  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
45  *
46  * @EulaEnd@
47  */
48 ////////////////////////////////////////////////////////////////////////////////
49 
50 #include <sys/select.h>
51 #include <stdio.h>
52 #include <unistd.h>
53 #include <string.h>
54 #include <stdlib.h>
55 #include <libgen.h>
56 #include <ctype.h>
57 #include <errno.h>
58 
59 #include "rnr/rnrconfig.h"
60 #include "rnr/opts.h"
61 #include "rnr/log.h"
62 
63 #include "Dynamixel/Dynamixel.h"
64 
65 #include "version.h"
66 
67 #include "dynashell.h"
68 #include "dynashell_cmd.h"
69 #include "dynashell_util.h"
70 
71 
72 //
73 // The command with option and argument values.
74 //
75 static char *Argv0; ///< the command
76 static char *OptsSerDevUri = NULL; ///< the serial device URI
77 static int OptsBaudRate = 1000000; ///< serial baudrate
78 static char *OptsScript = NULL; ///< script file
79 static bool OptsXTrace = false; ///< trace script
80 static bool OptsSilent = false; ///< silence output
81 
82 
83 /*!
84  * \brief Program information.
85  */
86 static OptsPgmInfo_T AppPgmInfo =
87 {
88  // usage_args
89  NULL,
90 
91  // synopsis
92  "Dynamixel simple shell.",
93 
94  // long_desc =
95  "The %P provides a simple command-line shell to the Dynamixel interface "
96  "provided by the library libDynamixel.",
97 
98  // diagnostics
99  NULL
100 };
101 
102 /*!
103  * \brief Command line options information.
104  */
105 static OptsInfo_T AppOptsInfo[] =
106 {
107  // -u, --uri <device_uri>
108  {
109  "uri", // long_opt
110  'u', // short_opt
111  required_argument, // has_arg
112  false, // has_default
113  &OptsSerDevUri, // opt_addr
114  OptsCvtArgStr, // fn_cvt
115  OptsFmtStr, // fn_fmt
116  "<device_uri>", // arg_name
117  "(Proxied) serial device interface. Syntax:\n" // opt desc
118  " [botsense://[hostname][:port]]/device",
119  },
120 
121  // -b, --baudrate <baud>
122  {
123  "baudrate", // long_opt
124  'b', // short_opt
125  required_argument, // has_arg
126  true, // has_default
127  &OptsBaudRate, // opt_addr
128  OptsCvtArgInt, // fn_cvt
129  OptsFmtInt, // fn_fmt
130  "<baud>", // arg_name
131  "Serial interface baudrate.", // opt desc
132  },
133 
134  // -s, --script <file>
135  {
136  "script", // long_opt
137  's', // short_opt
138  required_argument, // has_arg
139  false, // has_default
140  &OptsScript, // opt_addr
141  OptsCvtArgStr, // fn_cvt
142  OptsFmtStr, // fn_fmt
143  "<file>", // arg_name
144  "Shell script filename.", // opt desc
145  },
146 
147  // -x, --xtrace
148  {
149  "xtrace", // long_opt
150  'x', // short_opt
151  no_argument, // has_arg
152  true, // has_default
153  &OptsXTrace, // opt_addr
154  OptsCvtArgBool, // fn_cvt
155  OptsFmtBool, // fn_fmt
156  NULL, // arg_name
157  "Trace shell scripts.", // opt desc
158  },
159 
160  // -s, --silent
161  {
162  "silent", // long_opt
163  OPTS_NO_SHORT, // short_opt
164  no_argument, // has_arg
165  true, // has_default
166  &OptsSilent, // opt_addr
167  OptsCvtArgBool, // fn_cvt
168  OptsFmtBool, // fn_fmt
169  NULL, // arg_name
170  "Silence non-error responses.", // opt desc
171  },
172 
173  {NULL, }
174 };
175 
176 //
177 // Global Data
178 //
179 
180 /*!
181  * \brief Main command-line argument initialization.
182  *
183  * \param shell Dynamixel shell.
184  * \param argc Command-line argument count.
185  * \param argv Command-line argument list.
186  *
187  * \par Exits:
188  * Program terminates on conversion error.
189  */
190 static void MainInitArgs(DynaShell &shell, int argc, char *argv[])
191 {
192  FILE *fp;
193 
194  // name of this process
195  Argv0 = basename(argv[0]);
196 
197  // parse input options
198  argv = OptsGet(Argv0, &PkgInfo, &AppPgmInfo, AppOptsInfo, true,
199  &argc, argv);
200 
201  if( OptsSerDevUri != NULL )
202  {
204 
205  if( shell.m_pDynaComm == NULL )
206  {
207  OptsInvalid(Argv0, "Failed to create interface on %s@%d.",
209  }
210 
211  shell.m_pDynaChain = new DynaChain(*shell.m_pDynaComm);
212 
213  // create background thread and register chain - leave in ready state
214  if( shell.m_pDynaBgThread == NULL )
215  {
216  shell.m_pDynaBgThread = new DynaBgThread();
218  }
219  }
220 
221  if( OptsScript != NULL )
222  {
223  if( access(OptsScript, F_OK|R_OK) != 0 )
224  {
225  OptsInvalid(Argv0, "%s: %s.", OptsScript, strerror(errno));
226  }
227  else if( (fp = fopen(OptsScript, "r")) == NULL )
228  {
229  OptsInvalid(Argv0, "%s: %s.", OptsScript, strerror(errno));
230  }
231  else
232  {
233  shell.ScriptPush(OptsScript, fp);
234  shell.m_bIsInteractive = false;
235  }
236  }
237 
238  shell.m_bXTrace = OptsXTrace;
239  shell.m_bSilent = OptsSilent;
240 }
241 
242 /*!
243  * \brief Main initialization.
244  *
245  * \param shell Dynamixel shell.
246  * \param argc Command-line argument count.
247  * \param argv Command-line argument list.
248  *
249  * \par Exits:
250  * Program terminates on conversion error.
251  */
252 static void MainInit(DynaShell &shell, int argc, char *argv[])
253 {
254  MainInitArgs(shell, argc, argv);
255 
256  shell.PublishMap("bg", "Commands to control the vServo background thread.");
257  shell.PublishMap("clear", "Commands to clear run-time state.");
258  shell.PublishMap("dump", "Dump memory contents.");
259  shell.PublishMap("get", "Commands to get servo class object parameters.");
260  shell.PublishMap("load", "Commands to load files.");
261  shell.PublishMap("read", "Commands to read from the physical servos.");
262  shell.PublishMap("run", "Commands to run scripts.");
263  shell.PublishMap("save", "Commands to save files.");
264  shell.PublishMap("set", "Commands to set servo class object parameters.");
265  shell.PublishMap("write", "Commands to write to the physical servos.");
266 
270  //PublishShellTrainCommands(shell);
271 }
272 
273 /*!
274  * \brief Main clean-up on exiting.
275  *
276  * \param shell Dynamixel shell.
277  */
278 static void MainFini(DynaShell &shell)
279 {
280 }
281 
282 /*!
283  * \brief Example main.
284  *
285  * \param argc Command-line argument count.
286  * \param argv Command-line argument list.
287  *
288  * \par Exit Status:
289  * Program exits with 0 success, \h_gt 0 on failure.
290  */
291 int main(int argc, char *argv[])
292 {
293  DynaShell shell;
294  int rc;
295 
296  MainInit(shell, argc, argv);
297 
298  rc = shell.Run();
299 
300  MainFini(shell);
301 
302  return rc == DYNA_OK? 0: 8;
303 }
static bool OptsXTrace
trace script
void PublishShellServoCommands(DynaShell &shell)
Publish shell servo commands to shell.
virtual void RegisterChainAgent(DynaChain *pChain)
Register the Dynamixel chain for control and monitoring.
#define DYNA_OK
not an error, success
Definition: Dynamixel.h:78
void PublishShellInterfaceCommands(DynaShell &shell)
Publish shell dynamixel interface commands to shell.
Dynamixel shell utilities.
DynaComm * m_pDynaComm
dynamixel bus communication
Definition: dynashell.h:359
void ScriptPush(const char *sScriptFile, FILE *fp)
Push new script on the stack.
Definition: dynashell.cxx:669
static void MainInit(DynaShell &shell, int argc, char *argv[])
Main initialization.
void PublishMap(const char *sParent, const string &strBrief)
Publish new command map to shell.
Definition: dynashell.cxx:159
int main(int argc, char *argv[])
Example main.
static bool OptsSilent
silence output
static char * OptsScript
script file
static OptsPgmInfo_T AppPgmInfo
Program information.
void PublishShellCoreCommands(DynaShell &shell)
Publish shell core commands to shell.
static DynaComm * New(const char *sUri, int nBaudRate)
Archetype constructor to create a new Dynamixel bus communication derived instance.
Definition: DynaComm.cxx:179
bool m_bIsInteractive
[not] user interactive
Definition: dynashell.h:356
bool m_bXTrace
do [not] trace script
Definition: dynashell.h:357
static const PkgInfo_T PkgInfo
Definition: version.h:45
static int OptsBaudRate
serial baudrate
static void MainInitArgs(DynaShell &shell, int argc, char *argv[])
Main command-line argument initialization.
static char * OptsSerDevUri
the serial device URI
Dynamixel Chain Container Base Class.
Definition: DynaChain.h:75
Package version information.
DynaBgThread * m_pDynaBgThread
dynamixel chain
Definition: dynashell.h:361
static OptsInfo_T AppOptsInfo[]
Command line options information.
bool m_bSilent
do [not] silence non-error responses
Definition: dynashell.h:358
RoadNarrows Dynamixel Top-Level Package Header File.
The dynashell Command Class Interface.
static char * Argv0
the command
static void MainFini(DynaShell &shell)
Main clean-up on exiting.
DynaChain * m_pDynaChain
dynamixel chain
Definition: dynashell.h:360
int Run()
Command execution loop.
Definition: dynashell.cxx:884
The simple dynashell declarations.